SAM.gov Federal Contract Opportunities
Pricing
from $3.00 / 1,000 opportunity records
SAM.gov Federal Contract Opportunities
Official SAM.gov Get Opportunities API: federal contract leads by NAICS, set-aside, and deadline. Optional title keywords (they under-sample). Notice URLs and attachments. PPE target $3.00 per 1,000 records. No invented win scores.
Pricing
from $3.00 / 1,000 opportunity records
Rating
0.0
(0)
Developer
Max Mattox
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
MaxwellAI Apify Actor for federal contract leads from the official GSA Get Opportunities Public API v2. Default filters: NAICS, set-aside, and posted window / deadline. Title keywords are optional and under-sample. Each row is one notice: title, agency, deadline, SAM.gov URL, and attachment links.
Store keywords: SAM.gov scraper · federal contract opportunities · federal contract leads · NAICS filter · set-aside · 8(a) · SDVOSB · HUBZone · WOSB · solicitation tracker · GSA opportunities API · govcon · PPE Actor
| Actor name | sam-gov-opportunities |
| Store title | SAM.gov Federal Contract Opportunities |
| Namespace (on publish) | maxwellai/sam-gov-opportunities (confirm username on login) |
| Pricing (PPE target) | $3.00 per 1,000 records — event opportunity-record @ $0.003. Not live until Console monetization is set. |
| Data source | Official GET https://api.sam.gov/opportunities/v2/search only. No HTML scrape. |
| Status | Scaffold + SAMPLE_MODE. Not on the Store. Verified paid runs: $0. |
This is a data Actor. It does not write proposals, score win probability, or invent award amounts.
Honest market (live Store pages, 2026-09-13)
This niche is not empty. Do not claim first, only, or Featured.
| Actor | Users (on page) | Monthly (on page) | Notes |
|---|---|---|---|
jungle_synthesizer/samgov-scraper | 161 | 3 | 1.00/5; no-key frontend scrape; attachments |
fortuitous_pirate/sam-gov-scraper | 109 | 14 | ratings BLIND |
alizarin_refrigerator-owner/sam-gov-contracts---federal-opportunities-search | 9 | 1 | ratings BLIND |
jdepablos/samgov-opportunities-feed | 2 | 1 | PPE from $4/1k; no key |
skootle/sam-gov-federal-contracts | 1 | 1 | PPE from $7/1k; API key + USAspending join |
ryanclinton/sam-gov-contract-monitor | BLIND | BLIND | official API |
Wedge we can defend: official API (buyer brings a free SAM.gov key as an Actor secret), first-class NAICS + set-aside + deadline (not a hard title string), incremental sinceLastRun, attachment URLs, PPE cheaper than $4–$7/1k listings, copy that does not invent fit scores. USAspending join is a later toggle — not a current claim.
Live probe (2026-09-13, key confirmed HTTP 200): ncode=339113 + ptype=o over 30d → 23 notices (Endo Dry Compressor, EKG machine, Surgical Lights). Same NAICS + title personal protective equipment over 7d → 0. v1 has no ptype filter; still default to NAICS + set-aside and leave keywords empty.
What this Actor does
- Queries
https://api.sam.gov/opportunities/v2/searchwith your filters - NAICS codes and set-aside codes first; optional keywords (SAM.gov
titleparam — under-samples) - postedWithinDays lookback (clamped to SAM’s 365-day window)
- Optional sinceLastRun watermark in the Key-Value Store
- De-duplicates by
opportunityIdacross NAICS × set-aside combos - Pushes clean records to the default Dataset and charges PPE per record
Ideal for BD teams, GovCon consultants, and lead pipelines that need fresh federal contract leads without building against SAM.gov yourself.
Input
Matches .actor/input_schema.json. Empty filters = unfiltered search for that field.
| Field | Type | Description |
|---|---|---|
keywords | string | Optional title keyword (SAM.gov title). Leave empty — title strings under-sample |
naics | string[] | NAICS codes (2–6 digits). Each code is queried separately, then de-duped |
setAsideTypes | string[] | Official set-aside codes (SBA, 8A, HZC, SDVOSBC, WOSB, …) |
postedWithinDays | number | Lookback window (1–365). Ignored if sinceLastRun has a watermark |
maxItems | number | Cap on records returned / charged (1–10,000) |
sinceLastRun | boolean | Only opportunities posted after the last successful run |
API key is not an input field. Set secret SAM_API_KEY in Apify Console (see Environment).
See sample_input.json (labeled SAMPLE). Recommended: naics + setAsideTypes + postedWithinDays=30, keywords empty.
Common set-aside codes
| Code | Meaning |
|---|---|
SBA | Total Small Business Set-Aside |
SBP | Partial Small Business Set-Aside |
8A | 8(a) Set-Aside |
HZC | HUBZone Set-Aside |
SDVOSBC | SDVOSB Set-Aside |
WOSB | Women-Owned Small Business Set-Aside |
EDWOSB | EDWOSB Set-Aside |
VSA | Veteran-Owned Small Business (VA) |
Full list: GSA Opportunities API — Set-Aside Values.
Not in v1 (do not advertise)
- Notice-type filter (
ptype: solicitation / sources sought / …). API has it; v1 does not filter on it - Place-of-performance state filter
daysUntilDeadline, contact / POC, or description body (API can return POC; v1 does not emit it)- USAspending award join
- Bid/no-bid or win scores
noticeType is still emitted on each row when SAM returns type.
Output
Each dataset item (see .actor/dataset_schema.json):
| Field | Description |
|---|---|
opportunityId | SAM.gov notice ID |
title | Opportunity title |
agency | Agency path (fullParentPathName) |
naics | NAICS code |
setAside | Set-aside description / code |
postedDate | Posted date |
responseDate | Response / offer deadline |
placeOfPerformance | Formatted place string |
noticeUrl | Public SAM.gov notice URL |
attachmentUrls | Array of attachment / resource URLs |
Extra fields (solicitationNumber, noticeType, classificationCode, active) are included for power users. Unknown values are null or []. We do not fill them with guesses.
See sample_output.json (SAMPLE — fictional IDs, example.invalid hosts). Not live SAM.gov data.
Environment variables
| Variable | Required | Description |
|---|---|---|
SAM_API_KEY | Yes (live) | Free public API key from SAM.gov. Actor secret @SAM_API_KEY |
ACTOR_TEST_PAY_PER_EVENT | No | true to simulate PPE locally |
SAMPLE_MODE | No | true to push sample_output.json without calling SAM.gov |
How to get a free SAM.gov API key
- Create / sign in at https://sam.gov
- Open Account Details (Workspace → Profile / Account Details)
- Request / view your Public API Key (password re-entry may be required)
- Store it as
SAM_API_KEY— never commit it; this Actor redactsapi_keyin logs
Rate limits depend on account role (basic public keys have lower daily caps than entity / system accounts). Prefer entity registration for higher volume. Official docs: open.gsa.gov — Get Opportunities Public API.
FAQ
Is this the official API? Yes. Get Opportunities v2. Not a headless browser.
Why do I need a key? GSA requires api_key on every search. We cannot hide that. Competitors that skip the key are scraping HTML.
Do you include attachments? Yes — attachmentUrls from SAM resourceLinks when present.
Do you join USAspending? Not in v1.
Do you invent win scores? No.
Should I search “PPE” in the title? No. A live probe of NAICS 339113 + title personal protective equipment over 7d returned 0. Same NAICS + solicitation type over 30d returned 23. Use NAICS + set-aside.
Do you emit POC / contact? Not in v1. The API can return it; we do not advertise or map it yet.
Why is pricing $3 / 1,000? That is a target for Console monetization on publish day. It is not a live Store price and not a sales claim.
Run locally
cd apify-actors/sam-gov-opportunitiesnpm install# Demo without a SAM key (uses sample_output.json)SAMPLE_MODE=true npm start# Live API (requires key) + local PPE simulationexport SAM_API_KEY=your_key_herecp sample_input.json storage/key_value_stores/default/INPUT.jsonACTOR_TEST_PAY_PER_EVENT=true npm start
With Apify CLI (recommended)
npm install -g apify-cliapify run -p
Create .env from .env.example and fill in SAM_API_KEY.
Without SAM_API_KEY, the Actor falls back to SAMPLE_MODE so npm start still succeeds for scaffolding / CI.
Monetization (PPE)
- Model: Pay-per-event
- Event name:
opportunity-record - Target price: $3.00 / 1,000 records → $0.003 per event
- Implementation:
Actor.pushData(item, 'opportunity-record'). If charge is unavailable locally, the Actor stubs charge and still pushes data.
Configure the event price in Apify Console → Actor → Monetization on publish day (pricing is platform-side; code only emits the event name). Local test:
ACTOR_TEST_PAY_PER_EVENT=true SAMPLE_MODE=true npm start# Inspect storage/datasets/charging-log/ for simulated charges
This scaffold documents a pricing target. There are no live sales, Store rankings, or revenue claims.
Project layout
sam-gov-opportunities/├── .actor/│ ├── actor.json│ ├── input_schema.json│ ├── output_schema.json│ └── dataset_schema.json├── src/│ ├── main.js # Actor entry — fetch, map, push, PPE│ ├── sam-client.js # Official SAM.gov v2 search client│ └── mapper.js # Response → output schema├── sample_input.json├── sample_output.json├── Dockerfile├── package.json├── README.md└── PUBLISH-CHECKLIST.md
Publish (when Apify account is unlocked)
Do not push until Max has Apify credentials. Then follow PUBLISH-CHECKLIST.md.
apify loginapify push# Then set PPE pricing in Console: opportunity-record @ $0.003# Publish to Store under maxwellai/sam-gov-opportunities (confirm namespace)
Compliance notes
- Official public API only (no HTML scraping of authenticated SAM.gov pages)
- API key stays in env / Apify secrets (
@SAM_API_KEY) - Date windows respect the 1-year SAM.gov search limit
- Sample files are labeled SAMPLE and use
example.invalidattachment hosts
Categories (Store)
Lead generation · Business · Open data · Developer tools
Do not claim
- User counts, “#1”, Featured
- “45,000+ active opportunities” unless we count them this run
- Revenue, win rates, bid/no-bid scores
- That no other SAM.gov Actor exists
- Live Store price until Console monetization is saved
- Notice-type / state / contact / description / USAspending fields that v1 does not emit or filter
Support / MaxwellAI
Built for MaxwellAI (federal contract lead gen). API reference: GSA Open Technology — Get Opportunities Public API