Skip to content

Single opportunity

Fetch one complete opportunity by its 32-character notice_id. Use it when you already hold a notice_id (from search results, a sam.gov URL, or your own store) and want the full record.

Not subject to the history window

Unlike /opportunities/search, ID lookups return notices of any age, so this is the way to retrieve an old notice you already have the id for. Plan-window clamping does not apply here.

Parameters

  • notice_id (path): a 32-character hex string (regex ^[a-f0-9]{32}$, case-insensitive). Example: 00016e91148440e0b80537f6362f45ea.

No query parameters are accepted; field projection via ?fields= is not available on this endpoint (the full record is always returned).

notice_id is NOT the same as solicitation_number.

  • notice_id: a 32-character hex UUID like 002518857671489eb8688df91a64ecfb. This is the path parameter this endpoint accepts.
  • solicitation_number: a human-readable contract identifier like N0003925R4014 or W52P1J-25-R-0001. The same solicitation_number can appear on multiple notice rows (every amendment is its own notice).

If you have a solicitation_number and want the matching notice(s), use the search endpoint instead:

GET /api/v1/opportunities/search?solicitation_number=N0003925R4014

Calling /api/v1/opportunities/<solicitation_number> returns a structured 400 with a hint_url pointing at the search endpoint (see Errors below).

Response Format

The record is wrapped under opportunity, with two metadata fields alongside it:

{
  "opportunity": {
    "notice_id": "00016e91148440e0b80537f6362f45ea",
    "title": "FILTER ASSEMBLY,ELE",
    "notice_type": "Solicitation",
    "solicitation_number": "SPRMM126Q...",
    "agency": "DEPT OF DEFENSE.DEFENSE LOGISTICS AGENCY.DLA MARITIME...",
    "naics": ["334419"],
    "psc": ["5915"],
    "posted_date": "2026-05-22",
    "response_deadline": "2026-06-22T20:30:00+00:00",
    "description_text": null,
    "...": "all 59 opportunity fields, same shape as /opportunities/search data[]"
  },
  "has_raw_data": true,
  "last_updated": "2026-05-22T..."
}
  • opportunity: the same 59-field record returned by search. Reminders from the search domain primer: naics / psc are arrays; description_text is tri-state (real text / "NO_DESCRIPTION_AVAILABLE" / null); active is always "Yes" by design; set_aside_type "none" is tri-state.
  • has_raw_data: true if the original SAM payload is retained for this notice (available for notices ingested through the live pipeline; older backfilled rows may be false).
  • last_updated: when this notice last changed in our database. Same value /opportunities/delta sorts and filters on.

Errors

  • 400: path is not 32-char hex (e.g. a solicitation number passed by mistake). Returns a structured body with a hint_url pointing to the search endpoint so the caller can recover programmatically.
  • 404: well-formed id, no such notice in our database. Body: {"detail": "Opportunity not found"}.
  • 429: rate limit exceeded.

Sample 400 body when a solicitation number is passed instead of a notice_id:

{
  "detail": {
    "error": "invalid_notice_id",
    "message": "'36C24926R0057' is not a valid notice_id. notice_id is a 32-character hex string (example: 002518857671489eb8688df91a64ecfb). If '36C24926R0057' is a solicitation_number, use the search endpoint instead.",
    "hint_url": "/api/v1/opportunities/search?solicitation_number=36C24926R0057",
    "docs": "https://govconapi.com/api-guide/opportunity-detail#notice-id-vs-solicitation-number"
  }
}

Example

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://govconapi.com/api/v1/opportunities/00016e91148440e0b80537f6362f45ea"

A null description_text means not-yet-enriched

description_text: null does not mean "no description exists." It means enrichment has not run for this notice yet (rare on notices older than a day). Re-fetch later, or check the live description_url.

Worked example: an EPA Region 1 procurement (real)

Calling GET /api/v1/opportunities/0035baae11ef4760b1157425704b23c2 returns the EPA Region 1 Contracting Office's notice "H--Proficiency Testing (PT) Samples" for the New England Regional Laboratory at North Chelmsford, MA. Live response excerpt (verified 2026-06-02):

{
  "opportunity": {
    "notice_id": "0035baae11ef4760b1157425704b23c2",
    "title": "H--Proficiency Testing (PT) Samples ",
    "notice_type": "Combined Synopsis/Solicitation",
    "agency": "ENVIRONMENTAL PROTECTION AGENCY.ENVIRONMENTAL PROTECTION AGENCY.REGION 1 CONTRACTING OFFICE",
    "naics": ["325199"],
    "psc": ["H268"],
    "posted_date": "2026-04-10",
    "response_deadline": "2026-04-21T16:00:00+00:00",
    "solicitation_number": "68HE0126Q0009",
    "contact_name": "Williams, Brandon",
    "contact_email": "[email protected]",
    "contact_phone": "617-918-1965",
    "performance_street_address": "NE Regional Laboratory",
    "performance_city_name": "North Chelmsford",
    "performance_state_code": "MA",
    "performance_zip": "01863",
    "archive_date_detailed": "2026-05-06",
    "active": "Yes",
    "...": "39 additional fields per opportunity"
  },
  "has_raw_data": true,
  "last_updated": "2026-04-12T14:04:38.552010+00:00",
  "_sources": ["sam_opportunities"]
}

One detail call delivers the procurement context (agency hierarchy, NAICS, PSC, solicitation number), the awarding officer (name, email, phone), the place of performance (lab address), the lifecycle markers (posted_date, response_deadline, archive_date_detailed), and the SAM last_updated stamp. Per the active column is "Yes" by design rule, "active": "Yes" here even though the notice has archived; the canonical "is it currently open" answer is archive_date_detailed compared against today.

A REST API and MCP server for U.S. federal procurement data.

Get a free key, emailed instantly, or follow the quickstart.

Found something wrong, missing or confusing on this page?

Press Ctrl + Enter to send a note. Highlight text first and it travels with your note.