SAM.gov Contract Opportunities API — Federal RFPs & Bids
Pricing
$2.00 / 1,000 opportunity returneds
SAM.gov Contract Opportunities API — Federal RFPs & Bids
Export SAM.gov RFPs, solicitations, sources sought and award notices to JSON/CSV. No API key needed: official public daily extract (up to ~1 day old), or live API with your own free key. Filter NAICS, set-aside, type, state, date. $2 per 1,000 results.
Pricing
$2.00 / 1,000 opportunity returneds
Rating
0.0
(0)
Developer
AgentReady Tools
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
21 hours ago
Last modified
Categories
Features
Share
SAM.gov Contract Opportunities API — Federal RFPs & Bids (No API Key Needed)
Export US federal contract opportunities from SAM.gov — RFPs, solicitations, combined synopsis/solicitations, sources-sought and pre-solicitation notices, special notices and award notices — to JSON, CSV or Excel. Every run returns one normalized record per notice with NAICS, PSC, set-aside, agency path, place of performance, response deadline, points of contact and the SAM.gov link.
No API key needed. By default the Actor streams the official public SAM.gov daily extract of active contract opportunities (ContractOpportunitiesFullCSV, published by SAM.gov Data Services) and filters it for you. That data is up to about one day old. If you need live, up-to-the-minute data, add your own free SAM.gov API key and the Actor uses the official Get Opportunities API instead.
No page scraping, no shared keys, no unofficial endpoints.
For AI agents
Returns one normalized dataset item per SAM.gov federal contract opportunity, with title, dates, industry codes, contacts and source metadata.
MCP: connect your client to the Actor's Apify MCP endpoint. Example prompt: “Find 5 active federal solicitations for renovation work in Virginia using samgov-tools/samgov-opportunities.” Call with {} for recent active records without a SAM.gov key, or use 1–3 filters such as keywords, state and noticeType. Add maxItems to cap results. Read noticeId for identity, title and responseDeadline for triage, uiLink for the notice, and dataSource/extractDate for freshness. description is text in daily-extract mode and a URL in API mode; unavailable fields are null.
REST: set APIFY_TOKEN to your Apify token, then run with a small input:
curl --request POST \'https://api.apify.com/v2/acts/samgov-tools~samgov-opportunities/run-sync-get-dataset-items' \--header "Authorization: Bearer $APIFY_TOKEN" \--header 'Content-Type: application/json' \--data '{"keywords":"renovation","maxItems":5}'
JavaScript: install apify-client and set APIFY_TOKEN in your environment:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('samgov-tools/samgov-opportunities').call({keywords: 'renovation',maxItems: 5,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Example JSON item excerpt (illustrative daily-extract data; the complete field list and item appear below):
{"noticeId": "example-notice-id","title": "Office renovation","responseDeadline": null,"naicsCode": "236220","uiLink": "https://sam.gov/workspace/contract/opp/example-notice-id/view","description": "Renovation of office space.","dataSource": "sam.gov-daily-extract","extractDate": "2026-11-14T04:30:20.000Z"}
The REST response is an array of items; the JavaScript example reads the same dataset. See the complete example JSON item and all 26 field names in Output below. Filters can return no matches; {} requests up to 10 active notices from the last 30 days.
Paying agents without an Apify account (x402 / MPP)
An agent without an Apify account can buy a prepaid Apify API token from Apify AGI (agi.apify.com) with x402 (USDC on Base or Solana), MPP (Tempo or Solana) or Skyfire, then use it as the Apify API token in this README's REST example (Actor samgov-tools~samgov-opportunities) or as the bearer token for the Apify MCP server. This Actor uses limited permissions, which prepaid tokens require. Apify's current terms: minimum $1, the balance is a hard spending cap, the token expires 14 days after purchase, unused balance is non-refundable, and the feature is experimental. Check agi.apify.com for current terms before paying.
The token pays this Actor's normal pay-per-event prices: opportunity: $0.002 per stored opportunity. See Let your AI agent pay for Actor runs, x402 and MPP.
Who it's for
Government contractors, business-development and capture teams, researchers, and builders who want structured US federal contract opportunity data in JSON, CSV, or Excel — for lead lists, daily monitoring, or their own pipelines.
Two official data sources
| Daily extract (default, no key) | Live API (your own key) | |
|---|---|---|
| Source | Official public SAM.gov Data Services daily CSV extract | Official SAM.gov Get Opportunities Public API |
| Freshness | Up to ~1 day old (each item has extractDate) | Live |
| Key needed | No | Your own free SAM.gov public API key |
| Coverage | Active notices only | Active and inactive notices, up to one-year posting window |
description field | Notice description text | Description URL (needs your key to fetch) |
| Quotas | None from SAM.gov | Your key's daily request quota (a new personal key can be very limited) |
source = auto (default) picks the live API when you supply samApiKey, otherwise the daily extract. Force either with bulk or api. Each item says where it came from in dataSource (sam.gov-daily-extract or sam.gov-api).
Optional: get a free SAM.gov API key for live data
- Create a free SAM.gov individual account at sam.gov.
- Sign in, then open Account Details.
- Under Public API Key, generate or view your key. You may need to re-enter your password or an emailed one-time code.
- Paste the key into this Actor's
samApiKeyfield. It is a secret input.
Never share individual keys or use a shared personal key. Follow the SAM.gov Terms of Use. The Actor uses your key only during the run, never logs it, and never copies it to dataset items. Apify controls encrypted secret-input retention. This project contains no credentials.
Pricing
$2 per 1,000 opportunities ($0.002 each), pay-per-event, from either source. Apify platform usage for the run is included in that price.
- You are charged only for opportunities that are successfully stored. The charge event name is
opportunity. - Notices filtered out, duplicates within a run, rejected records, and download/API errors do not generate events.
- The run stops as soon as
maxItemsor your maximum charge is reached; the budget is checked before every charged item. - Runs are independent: running the same query again can store and charge for the same opportunity again.
- If a run fails or stops early, items already stored may already have been charged. There is no cross-run checkpoint or deduplication.
Input
| Field | Meaning | Default |
|---|---|---|
source | auto, bulk (daily extract, no key) or api (live, needs key) | auto |
samApiKey | Optional secret public API key from your own SAM.gov account | None (daily extract) |
keywords | Title search. API: official title parameter. Extract: every word must appear in the title (case-insensitive). Not a full-text search | None |
naics | 2–6 digits. API: ncode. Extract: prefix match (236 matches 236220) | None |
setAside | Official typeOfSetAside code; select from the input form | None |
noticeType | Official ptype: u, p, a, r, s, o, g, k, i | None |
state | 2-letter place-of-performance state, e.g. VA | None |
activeOnly | Boolean; extract mode requires Active: Yes. API mode excludes only string active: No (case-insensitive), retaining boolean false or missing status. Use false to disable the filter | true |
postedFrom | Inclusive start, MM/dd/yyyy or YYYY-MM-DD; range at most one calendar year | 29 days before postedTo (or today UTC) |
postedTo | Inclusive end, MM/dd/yyyy or YYYY-MM-DD; range at most one calendar year | Today UTC |
maxItems | Maximum stored (and charged) opportunities, 1–10,000 | 10 |
pageSize | API mode only: page size, 1–1,000 | 100 |
If only postedTo is supplied, the start defaults to 29 days before it. If only postedFrom is supplied, the end defaults to today. Ranges must be ordered and no longer than one calendar year. Raise maxItems to get more results; with an empty input the Actor returns the 10 newest active notices in a few seconds.
Example without a key (daily extract):
{"keywords": "renovation","naics": "236","setAside": "SBA","noticeType": "o","state": "CA","maxItems": 100}
Example with your own key (live API; the placeholder is not a real key):
{"samApiKey": "YOUR_OWN_PUBLIC_API_KEY","keywords": "renovation","naics": "236220","postedFrom": "10/16/2026","postedTo": "11/14/2026","maxItems": 100}
Output
Each dataset item is one opportunity. Stable fields from both sources: noticeId, title, solicitationNumber, type, baseType, postedDate, responseDeadline, naicsCode, classificationCode, setAside, setAsideCode, fullParentPathName, fullParentPathCode, organizationType, officeAddress, placeOfPerformance, pointOfContact, award, active, uiLink, description, resourceLinks, additionalInfoLink, archiveDate, dataSource, extractDate.
Missing fields are null. API mode preserves nested addresses, contacts, place of performance and award details; extract mode maps CSV columns into nested objects.
- Daily extract:
descriptionis the notice text from the extract;extractDateis when SAM.gov generated the file (from itsLast-Modifiedheader);resourceLinksis null (the extract has no attachment list).postedDatekeeps the extract'sYYYY-MM-DD HH:MM:SSformat. - Live API:
descriptionis the returned URL, not text. Anyapi_keyquery parameter is removed from stored links; fetching a description URL later requires your own key.extractDateis null.responseDeadlineaccepts the API'sreponseDeadLinetypo andresponseDeadLinespelling.
Attachments and external resources may have separate access or use restrictions. The Actor does not download attachments.
Example JSON output item (API mode), reduced from the official API's Example 1 (not a live capture):
{"noticeId": "5b345bbb7127b91a3ad577b203fc6f68","title": "Historic Office Renovation ","solicitationNumber": " 47PF0018R0023 ","type": "Award Notice","baseType": "Combined Synopsis/Solicitation","postedDate": "2018-05-04","responseDeadline": null,"naicsCode": "236220","classificationCode": "Z","setAside": null,"setAsideCode": null,"fullParentPathName": null,"fullParentPathCode": null,"organizationType": "OFFICE","officeAddress": {"zipcode": "60604","city": "CHICAGO","countryCode": "USA","state": "IL"},"placeOfPerformance": {"streetAddress": "517 E Wisconsin Ave","city": { "code": "53000", "name": "Milwaukee" },"state": { "code": "WI" },"zip": "53202","country": { "code": "USA" }},"pointOfContact": [{ "type": "primary", "title": "Contracting Officer " }],"award": {"date": "2018-05-04","number": "47PF0018C0066","amount": "800620"},"active": "Yes","uiLink": "https://beta.sam.gov/opp/5b345bbb7127b91a3ad577b203fc6f68/view","description": "https://api.sam.gov/prod/opportunities/v1/noticedesc?noticeid=5b345bbb7127b91a3ad577b203fc6f68","resourceLinks": null,"additionalInfoLink": null,"archiveDate": null,"dataSource": "sam.gov-api","extractDate": null}
Limits and behavior
Daily extract: the official file (~200 MB, active notices, newest first) is streamed and parsed on the fly — never fully loaded into memory — and the download is aborted as soon as maxItems matches are stored, so typical runs finish in seconds. A query with few matches scans the whole file (usually well under a minute). Network failures are retried; a mid-download failure restarts the download, and already stored notices are not stored or charged again.
Live API: requires a public key and a posting range of at most one year. Page size is at most 1,000. Daily request quotas depend on your account role; a basic personal key may be very limited. HTTP 429, server errors, and network or timeout failures receive up to four total attempts with backoff, jitter, and Retry-After support. Other HTTP errors fail clearly. Requests time out after 30 seconds, with 250 ms between pages. The API returns the latest version of each opportunity; it is not a historical version archive.
FAQ
Do I need a SAM.gov API key?
No. Without a key the Actor uses the official public SAM.gov daily extract (data up to ~1 day old). Add your own free key only if you need live data or inactive/archived notices.
How fresh is the no-key data?
SAM.gov regenerates the public extract daily. Each item carries extractDate so you can see exactly which file it came from. Notices posted after that time appear in the next day's extract, or immediately in API mode.
Does this Actor include a SAM.gov key?
No. Supply your own for live data. The Actor never logs the key or writes it to dataset items.
Does this scrape SAM.gov?
No. It uses only the official public Data Services extract and the official Get Opportunities Public API. It does not scrape SAM.gov pages or call the website's internal search.
Can I search the full notice text?
No. keywords matches opportunity titles only, in both modes. In daily-extract mode the description text is included in the output, so you can filter it further yourself.
Data use and sources
This Actor uses only official SAM.gov sources: the public Data Services daily extract and the Get Opportunities Public API. It does not scrape SAM.gov pages or use the website's internal search endpoints. Public contract opportunity records may be copied and distributed. Most SAM.gov material is not copyrighted, and US government works are generally public domain in the US; citation is appreciated. Check any third-party material separately. The Terms' D&B commercial-use restrictions concern D&B entity data, rather than public contract opportunity records; this Actor does not query entity data. Follow all applicable access and API-key terms.
- SAM.gov Data Services (public extracts)
- Official API documentation and role-based limits
- SAM.gov Terms of Use, key sharing, and data restrictions
- SAM.gov Account Details (Public API Key)
- Apify SDK Actor reference
Run locally
Requires Node.js 22+.
npm installnpm run buildnpm testmkdir -p storage/key_value_stores/default
Create storage/key_value_stores/default/INPUT.json (an empty {} uses the daily extract; for API mode enter your key in a local editor). The entire storage/ directory is gitignored. Avoid putting your key in shell commands or tracked files. Then run either:
npm start# Or, if the Apify CLI is installed:apify run
Dataset output is in local Apify storage. Delete the secret input file after use. Docker uses the Apify Node.js 22 Actor image and installs production dependencies in its final stage. Generate a lockfile with npm install when registry access is available, then use npm ci for reproducible builds. Tests use mocked fetch, in-memory CSV and fixtures only; they make no SAM.gov calls and require no credentials. The reduced fixture in test/fixtures/official-example.json is based on the official API's Example 1 (not a live capture).