SAM.gov & Grants.gov Scraper: Government Contracts & Grants avatar

SAM.gov & Grants.gov Scraper: Government Contracts & Grants

Pricing

from $2.40 / 1,000 opportunity returneds

Go to Apify Store
SAM.gov & Grants.gov Scraper: Government Contracts & Grants

SAM.gov & Grants.gov Scraper: Government Contracts & Grants

SAM.gov contract opportunities and Grants.gov federal grants in one feed, no API key needed. Contract filters (keyword, NAICS, agency, set-aside, notice type, due date) are applied to every row. Daily alerts and next-day amendment alerts.

Pricing

from $2.40 / 1,000 opportunity returneds

Rating

0.0

(0)

Developer

Your Evenings

Your Evenings

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

an hour ago

Last modified

Categories

Share

SAM.gov Contract & Grants.gov Opportunities API gives you new US federal contract opportunities (from SAM.gov) and grant opportunities (from Grants.gov) in one clean, filterable dataset, with no API key needed. Filter by keyword, NAICS code, agency, set-aside type, posted date and due date. Turn on monitor mode and schedule it daily to get a feed of only the new matches, or track solicitation numbers to get a row when one of them is amended or changes.

Not an official government product. This Actor is independent and is not affiliated with or endorsed by GSA, SAM.gov or Grants.gov. It uses data those services publish for the public.

Why this one

  • No SAM.gov API key needed. Contracts come from SAM.gov's public daily extract, so there's no key to register, rotate or rate-limit.
  • Filters are applied in code before you're charged, and you see how much matched. On SAM.gov contracts, notice type, NAICS, PSC code, place-of-performance state, set-aside, agency, due date and keywords (as whole phrases, listed in matchedKeywords) are checked on every row. On Grants.gov, agency and due date are checked in code and keywords use Grants.gov's own search. Each run reports how many opportunities matched out of how many were posted in the window, even when maxResults stops it returning more.
  • Saved dates roll forward. postedWithinDays counts back from each run, so a scheduled run always covers the latest days.
  • Contracts and grants in one schema, with monitorMode for new-only daily alerts.
  • Know when a solicitation you're bidding on changes. Add its number to trackSolicitationNumbers and get a row for each new amendment or notice, deadline move, notice type change or notice leaving the active list, with before and after values. Alerts are next-day, because SAM.gov's extract is refreshed daily.
  • You're told when the data is stale or a source fails. Every row has source_updated_at. If SAM.gov's extract is more than 36 hours old or empty, or either source fails, the run adds a free warning row and says so in its status message, so a quiet day isn't mistaken for a broken feed.

Quick start

Paste this into the JSON view of the Input tab and press Start. It returns up to 10 SAM.gov contract opportunities and up to 10 Grants.gov grants posted in the last 7 days that match "cybersecurity", newest first.

{
"opportunityType": "both",
"keywords": [
"cybersecurity"
],
"postedWithinDays": 7,
"maxResults": 10
}

For more ready-made inputs, see the example tasks.

Works with: SAM.gov (contract opportunities) · Grants.gov (grants)

Runs on Apify Apify. Use it from Make, Zapier, n8n n8n or the Apify API.

Use it as a SAM.gov scraper, a SAM.gov opportunities API without registering for a key, a Grants.gov API client, or a government contract alert for your bid team.

Where the data comes from

SourceWhatHow
SAM.gov Contract OpportunitiesSolicitations, combined synopsis/solicitations, presolicitations, sources sought, special notices, justifications (and award notices if you ask)SAM.gov's public daily data extract (Contract Opportunities CSV from SAM.gov Data Services), refreshed by SAM.gov once a day
Grants.govPosted and forecasted federal grant opportunitiesThe public Grants.gov REST API (search2 and fetchOpportunity)

No login, API key or browser is used. The SAM.gov extract lists notices newest first, so the Actor reads only the part that covers your date window and stops. In a test on 21 Oct 2026, a 7-day window meant reading about 23 MB (8,104 rows) of the extract, in under 2 seconds.

Freshness: SAM.gov contract notices come from SAM.gov's public daily extract, which SAM.gov regenerates once a day, so they can be up to about a day old (a notice posted today usually appears tomorrow). Grants.gov results are live, read from the Grants.gov API during the run. Every row has a source_updated_at timestamp (ISO 8601, UTC) and a source_updated_at_basis saying what it means:

  • sam_extract_last_modified: SAM.gov rows. The time SAM.gov last refreshed the extract file the row came from.
  • grants_opportunity_last_updated: Grants.gov rows. The opportunity's own last-updated time on Grants.gov.
  • grants_api_fetched_at: Grants.gov rows where Grants.gov gives no update time. The time the Actor fetched it from the live API.

What you can use it for

  • Daily bid alerts. Save your NAICS codes, set-asides and agencies, turn on monitor mode and schedule a daily run. You get only the notices you haven't seen before (see Pricing for what each run is charged).
  • Amendment alerts on bids you're working. Track the solicitation numbers your team is bidding on and see deadline moves, new amendments and notices that leave the active list the next morning.
  • Grant prospecting. Track new NIH, NSF, USDA or other agency funding opportunities by keyword, with award ceiling and floor, expected number of awards and eligible applicant types.
  • Market research. Pull every notice for an agency or NAICS code over a period and analyse it in a spreadsheet or BI tool.
  • Feeds for AI agents and CRMs. One normalised schema across both sources.

Example tasks (ready-made inputs)

Input

FieldWhat it doesDefault
opportunityTypeboth, contracts (SAM.gov) or grants (Grants.gov)both
keywordsAny of these words or phrasesnone
naicsCodesNAICS code prefixes, e.g. 541511 or 5415 (contracts only)none
agenciesText that the department, sub-agency, office or agency code containsnone
setAsideTypesSAM.gov set-aside codes (SBA, 8A, HZC, SDVOSBC, WOSB, ... or ANY) (contracts only)none
postedWithinDays / postedSinceDate window (N days back, or an exact YYYY-MM-DD start)last 7 days
dueAfterResponse deadline / close date on or after YYYY-MM-DDnone
maxResultsMax opportunities per source, newest first (0 = all matches in the window)10
monitorModeReturn only opportunities not returned by an earlier monitor runoff
emitBaselineOnFirstRunIn monitor mode, return all matches on the very first runon
trackSolicitationNumbersSAM.gov solicitation numbers to watch for changes (up to 500). When set, the run is a tracking run: see belownone
stateStoreNameNamed key-value store holding seen IDs and tracked-solicitation stateus-gov-opportunities-state
includeDescriptionShort plain-text description snippeton
includeContactsPoint-of-contact fields exactly as published on each noticeoff
includeAwardNoticesInclude SAM.gov award noticesoff
pscCodesProduct/service code (PSC) prefixes, e.g. R4, D or J059 (contracts only)none
placeOfPerformanceStatesPlace-of-performance states: 2-letter codes or names, e.g. VA, Maryland, DC (contracts only)none
samNoticeTypesKeep only these SAM.gov notice typesall
grantStatusesposted and/or forecastedboth
activeOnlySkip inactive SAM.gov noticeson

NAICS, set-aside, PSC and place-of-performance filters exist only on contract notices, so setting any of them skips Grants.gov (the run summary says so).

Place-of-performance state. The filter uses the state SAM.gov lists as the notice's place of performance. Many notices list none (about 3 in 4 in the extract on 22 Oct 2026, often services that can be performed anywhere or overseas), and those never match a state filter. The run summary says how many matching notices were excluded for that reason.

Example: small-business IT contracts from the VA plus related grants, due at least a week out:

{
"opportunityType": "both",
"keywords": ["software", "cybersecurity"],
"agencies": ["VETERANS AFFAIRS"],
"postedWithinDays": 7,
"dueAfter": "2026-10-28",
"maxResults": 100
}

Example: professional-support and IT services contracts (PSC R4 and D) performed in Virginia, Maryland or DC:

{
"opportunityType": "contracts",
"pscCodes": ["R4", "D"],
"placeOfPerformanceStates": ["VA", "MD", "DC"],
"postedWithinDays": 7,
"maxResults": 100
}

Example: daily alert for NAICS 5415 small-business set-asides:

{
"opportunityType": "contracts",
"naicsCodes": ["5415"],
"setAsideTypes": ["SBA", "SDVOSBC", "WOSB", "8A"],
"postedWithinDays": 2,
"maxResults": 0,
"monitorMode": true,
"stateStoreName": "it-set-aside-alerts"
}

Output

One row per opportunity. A contract (SAM.gov):

{
"source": "sam.gov",
"opportunityType": "contract",
"opportunityId": "e5a50c4bacc5478bbea335f8ca2c1d89",
"noticeId": "e5a50c4bacc5478bbea335f8ca2c1d89",
"solicitationNumber": null,
"title": "Systems Warfighting Architecture Navigator (SWAN) Operations, Sustainment, and Decision Support Services",
"agency": "DEPT OF DEFENSE",
"subAgency": "DEPT OF THE AIR FORCE",
"office": "FA8802 INTEGRATION OPERATION PIKPKE",
"agencyCode": "057",
"noticeType": "Special Notice",
"baseNoticeType": "Sources Sought",
"status": "active",
"naicsCodes": [],
"classificationCode": null,
"setAsideCode": null,
"setAside": null,
"postedDate": "2026-10-20",
"responseDeadline": "2026-10-27T00:00:00.000Z",
"responseDeadlineEstimated": false,
"archiveDate": "2026-10-29",
"placeOfPerformance": { "city": "El Segundo", "state": "CA", "zip": "90245", "country": "USA" },
"url": "https://sam.gov/opp/e5a50c4bacc5478bbea335f8ca2c1d89/view",
"descriptionSnippet": "Description Space Systems Command (SSC) is hosting a virtual Industry Day in anticipation of a forthcoming solicitation…",
"matchedKeywords": [],
"attachments": null,
"changeType": null,
"retrievedAt": "2026-10-21T17:59:02.158Z",
"source_updated_at": "2026-10-21T03:30:45.000Z",
"source_updated_at_basis": "sam_extract_last_modified"
}

A grant (Grants.gov), shortened:

{
"source": "grants.gov",
"opportunityType": "grant",
"opportunityId": "364134",
"solicitationNumber": "HHS-2027-ACF-ORR-ZU-0045",
"title": "Residential Services for Unaccompanied Alien Children",
"agency": "Department of Health and Human Services",
"subAgency": "Administration for Children and Families - ORR",
"noticeType": "Forecast",
"status": "forecasted",
"postedDate": "2026-10-21",
"responseDeadline": "2027-01-12",
"responseDeadlineEstimated": true,
"estimatedFunding": 280000000,
"awardCeiling": 5600000,
"awardFloor": 2000000,
"numberOfAwards": 50,
"assistanceListings": [{ "number": "93.676", "title": "Unaccompanied Children Program" }],
"fundingCategories": ["Income Security and Social Services"],
"url": "https://www.grants.gov/search-results-detail/364134",
"attachments": [],
"source_updated_at": "2026-10-21T17:49:44.000Z",
"source_updated_at_basis": "grants_opportunity_last_updated"
}

Both sources share the same fields; fields that don't apply to a source are null or empty. The Output tab has Overview, Contracts and Grants views. A run summary (filters, rows per source, rows scanned, extract date, timings, warnings) is saved as SUMMARY in the run's key-value store.

Matched vs scanned. SUMMARY.totals has, per source, how many rows were scanned, how many were posted in your date window, how many matched your filters and how many were returned (plus, in monitor mode, how many were skipped as already reported). The status message says the same in one line, e.g. "SAM.gov: 5 returned, 45 matched of 6,156 posted in the window (8,156 extract rows read)". So when maxResults cuts a run short, you can see how many more matches there were.

Warning rows (free). The run adds a status row (rowType: "status", never charged) when:

  • SAM.gov's extract was last refreshed more than 36 hours before the run (stale_data). SAM.gov normally refreshes it daily, so notices posted since then aren't in the run yet.
  • SAM.gov's extract had no rows (no_data), or its refresh time couldn't be read (unknown_freshness).
  • Grants.gov returned nothing for a search without keywords (no_data).
  • Either source failed (source_error).

Attachments. Grants.gov rows list the documents Grants.gov attaches to the opportunity (file name, description, folder and size) in attachments. Grants.gov's API doesn't give a download link, so url is null for files; open the opportunity's url to download them. For example, on 22 Oct 2026 DE-FOA-0003630 listed:

"attachments": [
{ "type": "file", "fileName": "NOFO_DE-FOA-0003630_UNLOCK.pdf", "description": "NOFO_DE-FOA-0003630_UNLOCK", "folder": "DE-FOA-0003630 (BASE)", "folderType": "Full Announcement", "sizeBytes": 1114696, "url": null }
]

Forecasts often have no attachments yet ([]). Document links Grants.gov lists are included with their url. Contract rows have attachments: null, because SAM.gov's public extract has no attachment data; use the notice's url to see its attachments on SAM.gov.

Contacts. Notices carry the contracting officer or agency contact. With includeContacts on, each row gets those fields exactly as published on that notice. They're never collected into a separate contacts list, and they're off by default.

Monitor mode: only new opportunities

  1. Turn on monitorMode, pick a stateStoreName for this saved search, and schedule the Actor (daily is typical).
  2. The first run returns all current matches (or, with emitBaselineOnFirstRun off, just remembers them).
  3. Later runs return only opportunities whose ID hasn't been returned before, with changeType: "new". A run with no new matches returns an empty dataset and costs only the Actor start.

If a run stops early because it reached your maximum charge, the undelivered opportunities are returned on the next run.

Solicitation tracking: amendment and change alerts

Put the solicitation numbers you care about in trackSolicitationNumbers and schedule a daily run. Numbers are matched without case, spaces or punctuation, so W912DY-26-R-0001 and w912dy26r0001 are the same.

{
"trackSolicitationNumbers": ["1240LT26Q0109", "W912DY26R0001"],
"stateStoreName": "my-bids-watchlist"
}

How it works:

  1. Each run reads SAM.gov's whole public daily extract (about 210 MB and 71,000 active notices on 22 Oct 2026; about 8 seconds per run in our platform tests) and picks out every active notice under your numbers. In SAM.gov's extract, each amendment or follow-on notice appears as a new notice ID under the same solicitation number.
  2. The first run for a number only remembers its current notices and returns a free status row (tracking_started, or not_found if the number isn't in the active extract yet).
  3. Later runs compare with what was saved and return one change row (rowType: "change") for each:
    • new_notice: a new notice or amendment under the number. changes lists the fields that differ from the previous latest notice (response deadline, notice type, base notice type, set-aside, NAICS, product/service code, title, archive date, place of performance, award fields, additional info link, description text), with before and after.
    • notice_updated: a notice already seen was edited in place (same fields, plus posted date).
    • notice_removed: a notice is no longer in the active extract. SAM.gov's extract doesn't say whether it was archived, cancelled or taken down, so check the notice on SAM.gov.
  4. Numbers with no change get a free unchanged status row, so every tracked number appears in every run.

Each change row has changeSummary (plain English), changes, trackedSolicitationNumber, comparedWithNoticeId, detectedAt and the usual contract fields of the notice, plus source_updated_at (the extract's Last-Modified time). The Tracked solicitation changes view in the Output tab shows them.

What to know:

  • Alerts are next-day, not real-time. SAM.gov refreshes the extract about once a day (on 21 and 22 Oct 2026, at about 03:30 UTC), so a change posted today is usually reported by a run the next day. Schedule the run after 04:00 UTC. If the extract hasn't been refreshed since the last run, the status rows say so.
  • Attachments aren't in the extract. A change that only adds or replaces an attachment is seen only if SAM.gov also posts it as a new notice or edits the notice's fields.
  • Search filters (keywords, NAICS, dates and so on) and monitorMode aren't used in tracking runs, and Grants.gov isn't checked.
  • Keep one stateStoreName per watch list. If a run stops at your maximum charge, the changes it couldn't return are kept and returned on the next run (a free changes_pending status row says how many).

A change row from a platform test run on 22 Oct 2026, shortened:

{
"rowType": "change",
"changeType": "new_notice",
"trackedSolicitationNumber": "1240-LT26-Q0109",
"changeSummary": "New Combined Synopsis/Solicitation posted 2026-10-21. Compared with notice d35a9184d1bf49fc93a17a1074c6b9a0 (2026-10-16): response deadline 2026-11-04T22:00:00.000Z → 2026-11-17T22:00:00.000Z; archive date 2026-11-19 → 2026-12-02; description text changed.",
"changes": [
{ "field": "responseDeadline", "label": "response deadline", "before": "2026-11-04T22:00:00.000Z", "after": "2026-11-17T22:00:00.000Z" },
{ "field": "archiveDate", "label": "archive date", "before": "2026-11-19", "after": "2026-12-02" },
{ "field": "description", "label": "description text", "before": "previous text", "after": "new text" }
],
"comparedWithNoticeId": "d35a9184d1bf49fc93a17a1074c6b9a0",
"source": "sam.gov",
"noticeId": "cbe71bb9577648beb6b5961f0588c070",
"solicitationNumber": "1240LT26Q0109",
"title": "4 GAOA Flaming Gorge Water System Buckboard in Ashley NF, Wyoming",
"noticeType": "Combined Synopsis/Solicitation",
"postedDate": "2026-10-21",
"responseDeadline": "2026-11-17T22:00:00.000Z",
"archiveDate": "2026-12-02",
"url": "https://sam.gov/opp/cbe71bb9577648beb6b5961f0588c070/view",
"detectedAt": "2026-10-22T09:51:13.933Z",
"source_updated_at": "2026-10-22T03:30:44.000Z",
"source_updated_at_basis": "sam_extract_last_modified"
}

Pricing

Pay per event. You pay for results, not compute:

EventWhen it is chargedPrice
Actor startOnce per run (per GB of memory; the default 256 MB run counts as one)$0.00005
OpportunityEach opportunity row returned, and each change row in a tracking run$0.003
Alert run with matchesMonitor mode and solicitation tracking: once per run that returns at least one new opportunity or change$0.01

Status rows in tracking runs (tracking_started, unchanged, not_found, changes_pending) are free.

The $0.01 "Alert run with matches" event covers both monitor runs that find new opportunities and tracking runs that find amendments or changes. A run that finds none pays nothing for this event. The event's short description on the Pricing tab mentions monitor mode only, but tracking runs are charged the same way.

Higher Apify plans get tier discounts (Silver −10%, Gold −20%). Prices on the Actor's Pricing tab are authoritative.

Examples at the base price:

  • The default run (10 contracts + 10 grants): 20 × $0.003 = about $0.06.
  • A one-off pull of 500 notices: 500 × $0.003 = $1.50.
  • A daily monitor run with 20 new matches: 20 × $0.003 + $0.01 = $0.07 (about $2.10 a month). Days with no new matches cost $0.00005.
  • A daily tracking run on 20 solicitation numbers where 3 changed: 3 × $0.003 + $0.01 = $0.019. A day with no changes costs $0.00005 (20 free status rows).

The Actor respects the maximum cost per run you set and says so in the status message when it stops early.

Use it from code, spreadsheets or an AI agent

  • Schedule it: Console > Schedules, daily, with monitorMode on, to get a new-opportunities feed.

  • Google Sheets, Make, Zapier, n8n, Slack: use the Actor's Integrations tab to send each run's dataset where you need it.

  • API (Python):

    from apify_client import ApifyClient
    client = ApifyClient("<YOUR_APIFY_TOKEN>")
    run = client.actor("yourevenings/us-gov-opportunities").call(run_input={"opportunityType": "contracts", "naicsCodes": ["541511"]})
    for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["source"], item["title"], item.get("agency"), item.get("responseDeadline"))
  • AI agents: the Actor can be run through the Apify MCP server, so Claude, ChatGPT or Cursor agents can call it with their own input.

AI agents can pay for runs themselves

AI agents can run this Actor and pay with stablecoins such as USDC through the x402 or MPP protocols, with no Apify account needed. The agent buys a prepaid, spend-capped Apify API token from Apify's Agent General Interface (AGI) and then runs the Actor with it as normal. Prepaid tokens only run Actors that use limited permissions, and this Actor does. Agentic payments are an experimental Apify feature, and the terms (minimum amount, expiry, usage limits) are set by Apify. See Apify's docs: Let your AI agent pay for Actor runs, x402 and MPP.

FAQ

Do I need a SAM.gov API key? No. Contract notices come from SAM.gov's public daily data extract and grants from the public Grants.gov API. Neither needs a key.

Is this an official SAM.gov or Grants.gov product? No. This is not an official government product. It's an independent tool and is not affiliated with or endorsed by GSA, SAM.gov, Grants.gov or any other agency. It uses their public data.

How current is it? Grants.gov is live. SAM.gov contract notices come from SAM.gov's public daily extract, so they can be up to about a day old compared with SAM.gov's website. Check source_updated_at on each row. Check the solicitation on SAM.gov before bidding: amendments and deadlines change.

Can it tell me when a solicitation is amended? Yes, next-day: list the numbers in trackSolicitationNumbers and schedule a daily run (see Solicitation tracking). Changes come from SAM.gov's daily extract, so they show up the day after SAM.gov publishes them, and attachment-only changes aren't visible.

Which notices are included by default? Active SAM.gov notices of every type except award notices, and posted plus forecasted grants. Use includeAwardNotices, samNoticeTypes and grantStatuses to change that.

Why did my NAICS filter return no grants? Grants don't have NAICS codes or set-asides, so those filters search contracts only.

Can I get older notices? Set postedSince to an earlier date. The SAM.gov extract covers currently published notices; archived notices aren't included.

Is it legal to use this data? It's US federal government information that agencies publish for the public. If you turn on contacts, use them only to respond to the notice they came from, and follow the laws that apply to you.

Feedback

Missing a filter, field or notice type? Open an issue on the Issues tab with your input and run ID, and it'll be looked at quickly.