SAM.gov Federal Contracts Scraper + Monitor — No Login, $3/1k
Pricing
from $3.00 / 1,000 results
SAM.gov Federal Contracts Scraper + Monitor — No Login, $3/1k
Scrape SAM.gov federal contract opportunities: RFPs, solicitations, sources sought, awards. Filter by keyword, NAICS, PSC, set-aside, notice type, agency, state, posted and due dates. Contracting officer contacts, full text. No login or cookies. MCP-ready for AI agents. $3 per 1,000 records.
Pricing
from $3.00 / 1,000 results
Rating
0.0
(0)
Developer
Fortuitous Pirate
Maintained by CommunityActor stats
7
Bookmarked
130
Total users
23
Monthly active users
2 days ago
Last modified
Categories
Share
SAM.gov Federal Contracts Scraper + Monitor
Pull federal contract opportunities from SAM.gov (solicitations, RFPs, RFQs, sources sought, presolicitations, special notices and award notices) into a clean spreadsheet or JSON feed. Each row has the contracting officer's name, email and phone, NAICS and PSC codes, set-aside, place of performance, response deadline (with days left), the full description text, direct download links for every attachment (SOWs, PWS, pricing sheets, amendments) and, on award notices, the winner's name, UEI, CAGE code and amount.
No SAM.gov account, no API key, no login, no proxy. Run it with no input and you get the 100 most recently updated active notices.
Four ways to use it, all in one actor:
| Mode | What you give it | What you get |
|---|---|---|
| Search | keywords and/or filters (NAICS, PSC, set-aside, notice type, agency, state, date windows) | every matching notice, newest first |
| Lookup | solicitation numbers, notice IDs or sam.gov/opp/.../view URLs | those notices, active or archived, with every amendment |
| Bulk | several keywords, or a CSV / Google Sheet URL (listUrl) mixing keywords, solicitation numbers and URLs | one merged, de-duplicated dataset |
| Monitor | the same filters plus onlyNew: true, on an Apify Schedule | only notices that are new or updated since the last run, with an optional webhook |
Who uses it
- Government contractors and BD teams: a daily list of new bids in your NAICS/PSC codes and set-aside, already filtered to deadlines you can still meet.
- Capture managers (bid/no-bid): every notice comes with its documents, contacts, days-to-deadline and due date in one row, so you can triage 50 opportunities without clicking through SAM.gov.
- Proposal teams: download the solicitation package (SOW, PWS, pricing template, Q&A, amendments) straight into the run's storage with
downloadAttachments. - Small businesses (8(a), HUBZone, SDVOSB, WOSB, VOSB): filter straight to the set-asides you qualify for.
- Subcontractors, teaming partners and GovCon lead generation: award notices with the winner's name, UEI, CAGE code and location, and contracting officer contacts by agency and office, exported to your CRM.
- Market research and AI agents: structured, LLM-ready JSON of what the government is buying, who is buying it and who won.
What you get per notice
| Field | Example | Notes |
|---|---|---|
opportunityId, solicitationNumber, parentNoticeId | 07ffa9495d33..., N0016426R3003 | parentNoticeId links an amendment to the original notice |
title, type, typeCode, status | Presolicitation, p, Published | |
postedDate, modifiedDate, responseDeadline, responseTimeZone, daysUntilDeadline | 2026-10-30T20:00:00+00:00, 9 | daysUntilDeadline is computed at scrape time; negative = already closed |
isActive, isCanceled, archiveDate, archiveType | true, false, 2026-11-30 | |
agencyName, subAgencyName, officeName, officeCode, officeAddress, organizationPath | DEPT OF DEFENSE > DEPT OF THE NAVY > NAVSEA > ... > NSWC CRANE | full federal hierarchy |
naicsCode, naicsCodes, pscCode | 541330, R425 | |
setAsideType, setAsideDescription | SBA, Total Small Business Set-Aside (FAR 19.5) | |
placeOfPerformance | { city, state, stateCode, zip, country, streetAddress } | |
description, descriptionText | SAM.gov summary (HTML) and the full notice text as plain text | |
contacts[], primaryContactName, primaryContactEmail, primaryContactPhone | Logan Kelley, logan.b.kelley.civ@us.navy.mil | every point of contact, plus the primary one as flat columns for CSV |
award | { amount, date, number, awardee, awardeeUei, awardeeCageCode, awardeeCity, awardeeState, awardeeZip, awardeeCountry } | award notices only, otherwise null |
attachments[], attachmentCount | filename, mimeType, size, type, accessLevel, postedDate, downloadUrl (+ storedKey, storedUrl when downloaded) | type: "link" entries point off-site (e.g. DIBBS, PIEE) |
samGovLink, scrapedAt | https://sam.gov/opp/<id>/view | |
matchedBy | N4008426R1026 | lookups and multi-keyword runs: which number / keyword produced the row |
changeType, firstSeenAt, matchedKeywords, monitorId | new / updated | monitor mode only |
Filters
Every filter is passed to SAM.gov's own search, so results match what you would see on sam.gov. All filters combine (AND). Multiple values inside one filter are OR-ed: ["VA", "MD"] means Virginia or Maryland.
| Input | What it does | Example |
|---|---|---|
keywords + keywordMode | Free-text search. Any word (default), all words, or exact phrase. One search per line; keywordList is the array form for API users | "cybersecurity", EXACT |
listUrl | CSV / TSV / text file or Google Sheet (shared as "anyone with the link"). First column; rows are detected as keyword, solicitation number or notice URL | https://docs.google.com/spreadsheets/d/.../edit |
naicsCodes | NAICS codes. Prefixes work: 5415 matches 541511, 541512, ... | ["541511", "541512"] |
pscCodes | Product Service Codes (classification codes) | ["DA10", "R425", "S201"] |
setAsideTypes | Set-aside codes | ["SBA", "8A", "SDVOSBC", "WOSB", "HZC", "VSA"] |
opportunityTypes | Notice types, by code or name | ["Solicitation", "Sources Sought", "k"] |
agencies | Department, agency or office by name, acronym or SAM.gov org ID | ["Department of Veterans Affairs", "DEPT OF THE NAVY"] |
states | Place-of-performance state codes | ["VA", "MD", "DC"] |
status / activeOnly | active (default), inactive (archived only) or all | "all" for award history |
postedWithinDays / postedFrom / postedTo | Posted (or last updated) window. Dates or relative values | "7 days", "2026-10-01" |
responseDeadlineFrom / responseDeadlineTo | Offer due-date window. Relative values count forward from today | "today" to "30 days" |
solicitationNumbers | Lookup by solicitation number (active or archived) | ["N4008426R1026", "36C26026Q0576"] |
noticeIds | Lookup by notice ID or https://sam.gov/opp/<id>/view URL | |
maxOpportunities | Stop after this many rows (default 100) | 500 |
sortBy | Recently modified (default) or relevance | -relevance |
fetchDetails | Full details (contacts, NAICS/PSC, set-aside, full text, award). Off = faster listing-only pull | true |
includeDescription | Off = leave the description fields empty for slim CSV exports | false |
includeAttachmentUrls | Attachment list with download URLs | true |
downloadAttachments + maxAttachmentSizeMb + maxAttachmentDownloads | Also save the public files into the run's key-value store | true, 25, 200 |
onlyNew + monitorId + firstRunMode + webhookUrl | Monitor mode (see below) | true, "it-services-va", "baseline" |
proxyConfiguration | Optional. SAM.gov answers Apify's cloud IPs directly, so none is used by default |
Date fields accept YYYY-MM-DD, MM/DD/YYYY, today, or relative values like 7 days, 2 weeks, 3 months (counted back for posted dates, forward for deadlines; -3 days / +3 days force a direction). Input names used by other SAM.gov tools are accepted as aliases: noticeTypes, setAsideCodes, maxResults, fetchFullDetails, includeAttachments, responseDueFrom/To, modifiedFrom/To, lookbackDays.
Input examples
Small-business IT bids due in the next 30 days
{"naicsCodes": ["541511", "541512", "541519"],"setAsideTypes": ["SBA", "8A"],"opportunityTypes": ["Solicitation", "Combined Synopsis/Solicitation"],"responseDeadlineFrom": "today","responseDeadlineTo": "30 days","maxOpportunities": 200}
Engineering support (PSC R425) still open, with the solicitation package downloaded
{"pscCodes": ["R425", "D302"],"responseDeadlineFrom": "today","responseDeadlineTo": "30 days","downloadAttachments": true,"maxAttachmentSizeMb": 25}
SDVOSB opportunities at the VA, with contacts
{"agencies": ["Department of Veterans Affairs"],"setAsideTypes": ["SDVOSBC", "VSA"],"postedWithinDays": 14}
Who won? Janitorial award notices from last month, archived included
{"pscCodes": ["S201"],"opportunityTypes": ["Award Notice"],"status": "all","postedFrom": "2026-09-01","postedTo": "2026-09-30"}
Bulk: several keyword searches in one run, merged and de-duplicated
{"keywords": "zero trust\nSOC as a service\nvulnerability assessment","opportunityTypes": ["o", "k", "r"],"maxOpportunities": 300}
Bulk from a sheet: { "listUrl": "https://docs.google.com/spreadsheets/d/1AbC.../edit#gid=0" } reads the first column; keywords, solicitation numbers and sam.gov URLs can be mixed in one list.
Track the solicitations you are bidding on (every amendment, active or archived)
{"solicitationNumbers": ["N4008426R1026", "36C26026Q1017", "W912C326CA008"]}
Monitor: daily feed of only new or updated notices, posted to Slack / Make / n8n
{"naicsCodes": ["236220", "238210"],"states": ["TX", "OK"],"opportunityTypes": ["o", "k", "p"],"postedWithinDays": 3,"onlyNew": true,"monitorId": "construction-tx","firstRunMode": "baseline","webhookUrl": "https://hooks.slack.com/services/..."}
Monitor mode
Set onlyNew: true and put the actor on an Apify Schedule. The actor remembers every notice it has returned in a key-value store named samgov-monitor-<hash of monitorId> in your account, and on each later run returns only:
changeType: "new": a notice it has not returned before, withfirstSeenAt;changeType: "updated": a notice whosemodifiedDatemoved since it was last returned (amendment, deadline change, Q&A posted).
firstRunMode decides what the very first run does: emitAll (default) returns everything that currently matches, baseline records it silently so the next run reports only changes. Notices beyond maxOpportunities stay unseen and come out on the next run, so nothing is lost. Use a different monitorId per watchlist to run several profiles side by side. Monitor mode also works with solicitationNumbers: you get a row only when one of your tracked bids is amended.
If webhookUrl is set, every run POSTs a JSON summary { monitorId, runId, newCount, updatedCount, itemsPushed, opportunities[first 50] } to it (Slack incoming webhooks, Zapier, Make, n8n or your own endpoint).
Migrating from the retired SAM.gov Opportunity Monitor actor: the store name is identical, so the same monitorId keeps your seen-state; noticeTypes, setAsides and lookbackDays work as-is and the keywords array becomes keywordList. Output: noticeId is opportunityId, samUrl is samGovLink, agency / subAgency / office are agencyName / subAgencyName / officeName.
Attachment downloads
includeAttachmentUrls (default on) lists every attachment with a direct downloadUrl that opens in any browser. With downloadAttachments: true the actor also saves each public file into the run's default key-value store and adds storedKey and storedUrl to the attachment, so Make/Zapier/n8n can pick the file up or you can fetch it with the Apify API. Files above maxAttachmentSizeMb (default 25), external links and controlled (login-only) files are listed with a skipReason instead. maxAttachmentDownloads (default 200) caps the number of files per run. Downloads are included in the row price; there is no extra charge per file.
A downloaded file gets, for example, "storedKey": "66becf06-Performance_Work_Statement_(PWS)_-_MARFORRES_FDET_Engineer_Support_Services_Oct2026.docx" and "storedUrl": "https://api.apify.com/v2/key-value-stores/OhDstkbmAkDoki5PR/records/66becf06-Performance_Work_Statement_%28PWS%29_-_MARFORRES_FDET_Engineer_Support_Services_Oct2026.docx?signature=..." (a signed link that works without a token).
Output
One row per notice. A real row from a run with pscCodes: ["R425","D302"], responseDeadlineFrom: "today", responseDeadlineTo: "30 days" (description trimmed):
{"opportunityId": "07ffa9495d334260ab03488c5b5ee856","solicitationNumber": "N0016426R3003_DRAFT","title": "Draft RFP for DRPM RAS ME RAS 1.0 and MCM RAS 2.0 Professional Support Services","description": "THIS IS A DRAFT SEAPORT-NxG SOLICITATION TO REQUEST INPUT FROM INDUSTRY - THE GOVERNMENT MAY NOT RES ...","descriptionText": "THIS IS A DRAFT SEAPORT-NxG SOLICITATION TO REQUEST INPUT FROM INDUSTRY - THE GOVERNMENT MAY NOT RESPOND TO ALL QUESTIONS POSTED BUT WILL CONSIDER EACH FOR FINAL SOLICITATION. This Advance Notice/Draft is issued by Naval ...","type": "Presolicitation","typeCode": "p","status": "Published","postedDate": "2026-10-21T14:54:46+00:00","modifiedDate": "2026-10-21T14:54:46+00:00","responseDeadline": "2026-10-30T20:00:00+00:00","responseTimeZone": "America/New_York","daysUntilDeadline": 9,"isActive": true,"isCanceled": false,"agencyName": "DEPT OF DEFENSE","subAgencyName": "DEPT OF THE NAVY","officeName": "NSWC CRANE","officeCode": "N00164","officeAddress": { "streetAddress": "WARFARE CENTER", "streetAddress2": "300 HIGHWAY 361", "city": "CRANE", "state": "IN", "zip": "47522-5001", "country": "USA" },"organizationPath": "DEPT OF DEFENSE > DEPT OF THE NAVY > NAVSEA > NAVSEA WARFARE CENTER > NSWC CRANE","parentNoticeId": "f5771a27a0d4424f9e8e3ce9b4a884ef","naicsCode": "541330","naicsCodes": ["541330"],"pscCode": "R425","setAsideType": "SBA","setAsideDescription": "Total Small Business Set-Aside (FAR 19.5)","archiveDate": "2026-11-30","archiveType": "autocustom","placeOfPerformance": { "streetAddress": "Washington Navy yard, DC 20376", "city": null, "state": null, "stateCode": null, "zip": "20376", "country": null, "countryCode": null },"contacts": [{ "name": "Logan Kelley", "email": "logan.b.kelley.civ@us.navy.mil", "phone": "", "fax": "", "title": null, "type": "primary" }],"primaryContactName": "Logan Kelley","primaryContactEmail": "logan.b.kelley.civ@us.navy.mil","primaryContactPhone": "","award": null,"attachmentCount": 4,"attachments": [{"filename": "PIEE Solicitation Module Link for N0016426R3003_DRAFT","mimeType": "","size": 0,"resourceId": "2366e246dbe84ec1a4c483c775cfb005","accessLevel": "public","postedDate": "2026-10-16T11:51:56.747+00:00","type": "link","description": "PIEE Solicitation Module Link for N0016426R3003_DRAFT","exportControlled": false,"downloadUrl": "https://piee.eb.mil/sol/xhtml/unauth/search/oppMgmtLink.xhtml?noticeId=N0016426R3003_DRAFT¬iceType=Presolicitation"}],"samGovLink": "https://sam.gov/opp/07ffa9495d334260ab03488c5b5ee856/view","scrapedAt": "2026-10-21T16:10:27+00:00"}
Award notices fill award, for example { "amount": "114511.00", "date": "2026-10-21", "number": "15BGCS27D10900001", "awardee": "Young Veterans Electrodiagnostic Ser., PLLC", "awardeeUei": "Q2HBKZ3BPNG7", "awardeeCageCode": "9XHF5", "awardeeCity": "Versailles", "awardeeState": "KY", "awardeeZip": "40383", "awardeeCountry": "UNITED STATES" }.
The dataset has three ready-made table views: Opportunities (triage columns incl. days left), Contacts (agency, office, contracting officer, email, phone) and Monitor changes.
Each run also saves a summary in the key-value store record OUTPUT: rows returned, total matches on SAM.gov per keyword, the agencies your names were matched to, files downloaded, monitor counts, and any notices that failed. If something breaks mid-run, every row already collected stays in the dataset and the summary says PARTIAL.
Pricing
Pay per result: $3 per 1,000 notices plus a $0.005 start fee per run (per GB of memory; the actor runs at 1 GB). Contacts, full text, attachment URLs, attachment downloads and the monitor are all included in the row price; there are no add-on events. Monitor runs only pay for the new or updated rows they return, so a daily watchlist that finds 5 new bids a day costs about $0.60 a month (150 rows + 30 start fees).
Examples: a daily feed of 50 notices = $0.155 per run; a 2,000-row market pull = $6.
Limits and tips
- SAM.gov caps a single query at 10,000 notices. Split larger pulls into date windows with
postedFrom/postedToor into several keywords. - "Posted" dates: SAM.gov's search index dates a notice by its latest publication, so an amended notice counts as recently posted. That is usually what a bid feed wants; use
parentNoticeIdto group amendments with their original. - Faster runs: turn off
fetchDetailsandincludeAttachmentUrlswhen you only need titles, numbers, dates and agencies (one request per page instead of three per notice). - Agency names: check the log or the
OUTPUTsummary to see which SAM.gov organization each name matched. If a name is ambiguous, use the numeric organization ID it shows. - Controlled attachments: files with
accessLevelother thanpublicneed a SAM.gov login; the actor lists them but cannot download them. - Notice IDs vs solicitation numbers: a solicitation number can have several notices (original, amendments, award).
solicitationNumbersreturns all of them;noticeIdsreturns exactly one. - Timeouts: the default run timeout is 5 minutes. Raise it in the run options for big pulls with details and attachment downloads.
Integrations and AI agents
Results export as JSON, CSV, Excel, XML or HTML from the dataset tab, or through the Apify API, webhooks and SDKs.
from apify_client import ApifyClientclient = ApifyClient("MY_APIFY_TOKEN")run = client.actor("fortuitous_pirate/sam-gov-scraper").call(run_input={"naicsCodes": ["541511", "541512"],"setAsideTypes": ["SBA", "8A"],"responseDeadlineFrom": "today","maxOpportunities": 200,})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row["solicitationNumber"], row["daysUntilDeadline"], row["primaryContactEmail"])
The JavaScript client (apify-client) works the same way: client.actor('fortuitous_pirate/sam-gov-scraper').call(input) then client.dataset(run.defaultDatasetId).listItems().
- Schedules: run it hourly or daily; combine with
onlyNewso each run only returns changes. - Webhooks: Apify run webhooks fire when a run finishes;
webhookUrladditionally posts the new rows themselves. - Make, Zapier, n8n: use the Apify app to start the actor and read the dataset, or point
webhookUrlat a scenario trigger. - Google Sheets, Slack, Airbyte, GitHub: available through Apify integrations.
- MCP / AI agents: the output is clean JSON that assistants can use through the Apify MCP server. Ask: "find open SDVOSB construction solicitations in Texas due in the next three weeks and list the contracting officers".
FAQ
Do I need a SAM.gov account or API key? No. The actor reads the same public data the sam.gov website shows to anonymous visitors.
Can I get archived and awarded notices? Yes. Set status to all or inactive, or look them up directly with solicitationNumbers / noticeIds.
Are the attachment files downloaded? The URLs are always included. Set downloadAttachments: true to also store the public files in the run's key-value store (storedUrl on each attachment).
How do I get only new opportunities each day? onlyNew: true plus a schedule. The first run returns (or, with firstRunMode: "baseline", silently records) everything that currently matches; later runs return only new and updated notices.
Why does a notice show up again in monitor mode? Its modifiedDate changed (amendment, Q&A or deadline change); the row says changeType: "updated". A run whose filters match nothing finishes successfully with an empty dataset.
Is this data legal to use? SAM.gov contract opportunity data is published by the U.S. government for public use. Notices name government points of contact; if you are in the EU or UK, you are responsible for having a lawful basis for processing personal data.
This actor is an independent tool. It is not affiliated with or endorsed by the U.S. General Services Administration (GSA) or SAM.gov. Feature requests and problems: open an issue on the Issues tab.