WW-83 (WING-80) — SAM.gov Opportunities API recon (P3 precursor)¶
Spike research. Produced by fleet worker (grok kind, AndyGreatRoomPC / Gronktayvius), 2026-07-24. DOC-ONLY — no code, no git changes in this spike.
Verdict: CONDITIONAL-GO for a daily-pull + cache pipeline¶
A pure-JSON Get Opportunities Public API (v2) exists for open contract notices, with filters that matter to a veteran going independent (set-aside including SDVOSB/VOSB, NAICS, notice type, dates, place of performance). A daily-pull + local cache is technically feasible if WorkWingman operates under an entity-associated API key (or system account) at the ~1,000 requests/day tier — not under a bare individual key at ~10 requests/day.
Not a green light for bid scoring. This spike covers discovery, filters, and registration reality only. A “win-likelihood %,” composite bid score, or any eligibility oracle is out of scope and banned for downstream product work (ticket constraint + Kerr eligibility-oracle rule from the USAJOBS veteran spikes). Surface facts (set-aside code, NAICS, deadline, agency, link-out to SAM.gov); never rank “how likely you win.”
Business-vs-technical constraint¶
| Model | Fit | Notes |
|---|---|---|
| WorkWingman entity-associated key (or non-federal system account), server- or desktop-side daily pull → cache, users browse cache | Primary path for P3 | Matches “daily-pull + cache” ask; needs entity registration (or approved system account) for usable rate limits; ToS forbids sharing individual keys |
| BYO individual SAM key, live search per user | Possible for power users | Basic non-entity individual key is ~10 req/day — too thin for multi-filter browse + description fetches; entity-associated individual keys get ~1,000/day but require user entity registration |
| Unauthenticated HTML scrape of sam.gov | NO-GO | SAM Terms of Use prohibit bots/scraping for data gathering; use public APIs and Data Services extracts only |
| Bulk Data Services CSV/extracts (active opportunities) + API for deltas/detail | Strong complement | Official docs point active notices to Data Services; active data described as updated daily; reduces API burn for full-corpus refresh |
Recommendation: Company (or product-entity) key at entity tier for scheduled pull → cache; optional user BYO only if they already have entity-tier access. Prefer Data Services bulk for daily full active set when practical; use Opportunities API for filtered deltas, single-notice refresh, and description/attachment links. Link-out to SAM.gov for bid submission — WW never submits proposals.
1) SAM.gov Opportunities API surface¶
1.1 Endpoints (official)¶
| Env | Search URL |
|---|---|
| Production | https://api.sam.gov/opportunities/v2/search |
| Alpha (prodlike) | https://api-alpha.sam.gov/opportunities/v2/search |
Source: Get Opportunities Public API.
Related (not the public search product path):
| Concern | Notes |
|---|---|
| Opportunity description | Response description is a URL (e.g. .../opportunities/v1/noticedesc?noticeid=...); caller must append public API key to download body text. Counts as additional request(s) against the key. |
| UI link | uiLink / SAM opportunity page — deep-link for humans; docs note some UI paths expect roles (treat as “open in browser / verify on SAM”). |
| Attachments | resourceLinks — direct download URLs when present. |
| Data Services (bulk) | Active + archived Contract Opportunities extracts under SAM.gov Data Services (see official overview links on the API page). |
| Opportunity Management API | Separate authorized create/update path for contracting officers — not the public discovery API for this product. |
Freshness (official): “This API only provides the latest active version of the opportunity. … All active notices in SAM.gov are updated daily and all archived notices are updated on a weekly basis.” Full version history is via Data Services, not this search API.
1.2 Authentication¶
- Required: public
api_keyquery parameter on every request. - How to get a key: SAM.gov account → Account Details → generate/view public API key (password or one-time password flow depending on domain; Entity API docs describe OTP-to-email for key reveal). Production keys on sam.gov; alpha keys on alpha.sam.gov.
- Key hygiene (Terms of Use): do not share an individual account API key; rotate key and system-account password every 90 days; system keys only within the org that owns the system account; if sharing data publicly, only from public API variants.
1.3 Rate limits (tiers)¶
The Opportunities public API page states requests/day are limited by federal / non-federal / general roles, but does not print a numeric table on that page.
The Entity Management API docs (same SAM public-key model) and System Account user guides document the default personal/system tiers used across SAM public APIs:
| Account type | Key type | Default daily limit (documented) |
|---|---|---|
| Non-federal individual not associated with an entity / no role | Personal API key | 10 requests / day |
| Non-federal individual associated with an entity / with a role | Personal API key | 1,000 requests / day |
| Federal individual | Personal API key | 1,000 requests / day |
| Non-federal system | System account API key | 1,000 requests / day (some guide editions list higher non-fed system tiers — treat as verify against current FSD/System Account guide before assuming >1k) |
| Federal system | System account API key | 10,000 requests / day |
Open question (flagged): Whether Opportunities is exactly the same numeric table as Entity Management is implied by shared SAM key/role model and third-party + System Account guides, but the Opportunities page itself only says “limited based on … roles.” Confirm with FSD article API rate limits / System Account and Individual API Key User Guide before capacity planning freezes.
Pagination budget: limit max 1000 records/page (default 1 — easy footgun); offset
starts at 0. One well-scoped query can return up to 1,000 notices per request. Description
bodies are extra calls.
Pipeline implication:
| Strategy | 10/day basic key | ~1,000/day entity key |
|---|---|---|
| Daily multi-filter pull + pagination + some description enrich | Impractical | Feasible if queries are batched and descriptions are selective |
| Single daily bulk CSV from Data Services + sparse API | Possible (CSV may not need key; API for exceptions only) | Comfortable |
| Per-user live interactive multi-page search | Burns quota fast | Only if BYO entity key |
1.4 Required query shape¶
| Parameter | Required? | Notes |
|---|---|---|
api_key |
Yes | Public key |
postedFrom / postedTo |
Yes | MM/dd/yyyy; max 1-year window between from and to |
| All other filters | No | See §2 |
Procurement types (ptype): u J&A, p presolicitation, a award, r sources sought, s
special notice, o solicitation, g surplus sale, k combined synopsis/solicitation, i DoD
intent to bundle. Retired: f, l.
For a contractor opportunity pipeline, primary live types are typically o, k,
p, r (and sometimes s); award notices (a) are intelligence, not open bids.
1.5 Response shape (summary)¶
Top-level:
totalRecords, limit, offset, opportunitiesData[], links[]
Per opportunity (high-value fields for WW discovery — not exhaustive):
| Field | Use in product |
|---|---|
noticeId |
Stable id for cache upsert / description fetch |
title, solicitationNumber |
List UI |
postedDate, responseDeadLine / reponseDeadLine (typo in docs/examples) |
Freshness + deadline chips — display only |
type, baseType, active |
Notice type + active/archived |
typeOfSetAside / setAsideCode, typeOfSetAsideDescription / setAside |
Set-aside chips (factual) |
naicsCode, classificationCode |
Industry filters / chips |
fullParentPathName / fullParentPathCode |
Agency path (prefer over deprecated dept/subtier/office) |
pointOfContact[] |
Optional contact block |
placeOfPerformance, officeAddress |
Location filters / display |
description |
URL to body, not inline HTML/text |
uiLink |
Open on SAM.gov |
resourceLinks |
Attachments |
award (+ awardee.ueiSAM when present) |
Award notices only — market research, not “open bid” |
Example notice id shape (from official docs): hex string e.g. 5b345bbb7127b91a3ad577b203fc6f68.
2) Set-aside and NAICS filters (individual / small veteran contractor relevance)¶
2.1 API filters¶
| Query param | Meaning |
|---|---|
typeOfSetAside |
Set-aside code (see table) |
typeOfSetAsideDescription |
Set-aside description text (secondary; prefer code) |
ncode |
NAICS, max 6 digits |
ccode |
Classification / PSC-style classification code |
state, zip |
Place of performance |
organizationCode, organizationName |
Org filter (organizationName can search dept/subtier; general search noted) |
title |
Title keyword |
rdlfrom / rdlto |
Response deadline window (1-year range if both set) |
ptype |
Notice type |
status |
Documented as Coming Soon (active, inactive, archived, cancelled, deleted) — do not depend on it for v1 |
2.2 Official set-aside codes (API table)¶
Only one set-aside value accepted per request field (API docs).
| Code | Meaning | Relevance to individual / small veteran contractor |
|---|---|---|
SBA |
Total Small Business Set-Aside (FAR 19.5) | Core small-business pool |
SBP |
Partial Small Business Set-Aside | Partial small-business |
8A / 8AN |
8(a) set-aside / sole source | Requires 8(a) program participation — not automatic for veterans |
HZC / HZS |
HUBZone set-aside / sole source | Geographic HUBZone cert |
SDVOSBC / SDVOSBS |
SDVOSB set-aside / sole source (FAR 19.14) | Primary federal set-aside filter for service-disabled veteran-owned small business |
WOSB / WOSBSS |
WOSB set-aside / sole source | Women-owned program |
EDWOSB / EDWOSBSS |
EDWOSB set-aside / sole source | Economically disadvantaged WOSB |
LAS |
Local Area Set-Aside (FAR 26.2) | Disaster/local preference contexts |
IEE, ISBEE, BICiv |
Indian enterprise set-asides (DOI / IHS-specific) | Niche |
VSA / VSS |
VOSB set-aside / sole source (VA-specific per API table) | Veteran-owned; API labels these as Department of Veterans Affairs–specific |
Product guidance (filters only, never scores):
- Offer explicit user toggles: e.g. SDVOSB set-asides (
SDVOSBC/SDVOSBS), small business (SBA/SBP), VA VOSB (VSA/VSS), plus free NAICS list from profile — same spirit as USAJOBS hiring-path chips: facts + optional filters, not default silent re-rank. - Do not imply that viewing an SDVOSB notice means the user is eligible. Eligibility requires SBA VetCert (and size standards / ownership rules) — WW may checklist “have you certified?” but must not declare “you qualify.”
- Unrestricted (null set-aside) notices remain valid open competitions; filtering them out is a user choice, not a default “veteran mode.”
2.3 NAICS¶
- Filter:
ncode(up to 6 digits). Response:naicsCode. - Users (and WW as entity) self-select NAICS at SAM registration; Census NAICS is the reference taxonomy. Product can map veteran occupational interests → suggested NAICS lists later (separate spike) — still never a bid-win score.
3) UEI + SAM entity registration reality (individual going independent)¶
3.1 Two different things (do not conflate)¶
| Path | What you get | Can bid as prime? |
|---|---|---|
| Unique Entity ID only | 12-character UEI; legal name + physical address validation | No — official: if you only get a UEI, you cannot apply directly for federal awards |
| Full entity registration | UEI assigned during process + active registration (banking/EFT, reps & certs, NAICS, etc.) | Yes (for awards that require SAM registration) — renew every 365 days |
Source: Entity registration / Get Started.
3.2 Official timing (what we can claim)¶
- SAM.gov customer-service line: “Registration can take up to 10 business days to become active.”
- Registration is free on the official site; paid “expedite” third parties are a known scam vector — product copy should steer users only to sam.gov and fsd.gov.
- Wall-clock for a clean sole prop is not guaranteed to be “a few days”: entity validation failures, TIN/name mismatches, and document back-and-forth extend timelines. Pitch-safe: “often measured in business days up to about two weeks per SAM’s own guidance; longer if validation fails.” Pitch-unsafe: “instant,” “same day active registration,” or fixed “always N days.”
3.3 What an individual typically needs (checklist-level)¶
From official checklist / get-started materials (high level — full list in GSA Entity Registration Checklist PDF):
- Login.gov account → SAM.gov profile
- Legal business name + physical address (entity validation)
- TIN: EIN or, for sole proprietors, SSN is commonly accepted in government quick-start materials; many guides strongly encourage EIN so SSN is not the business identifier
- Entity structure (e.g. sole proprietorship), banking for EFT, points of contact, NAICS, etc. for full registration
- Optional/adjacent: CAGE code often obtained as part of registration flow (not re-researched end-to-end in this spike)
Realistic for target user? Yes, with friction — free, official path; sole proprietors are first-class entity structures. Friction is form completeness + validation lag + annual renewal, not a closed door. Unknown without user study: drop-off rate for veterans doing this alone; validation failure rate for sole props using home addresses / DBA names.
3.4 SDVOSB / VOSB certification is separate from SAM¶
- SAM registration ≠ SBA Veteran Small Business Certification (VetCert).
- To compete for SDVOSB/VOSB set-asides, firms need SBA certification via VetCert / MySBA Certifications — not just a SAM flag.
- Timeline (open / variable): SBA public release (2025-11-11) claimed backlog cleared and processing averaged ~12 days at that time, after earlier peaks (~81 days end of 2024). Third- party guides still often quote 60–90 days. Do not hard-code a single SLA in product copy — point users to SBA and treat duration as variable.
3.5 Relevance to WorkWingman GTM layers¶
| User goal | Minimum external setup | WW role |
|---|---|---|
| Browse federal contract opportunities in-app | None (if WW hosts cache) | Discovery UI + link-out |
| Bid as prime | Active SAM registration (+ UEI) | Checklist / deep-link to sam.gov; never register for them |
| Bid on SDVOSB/VOSB set-asides | SAM + SBA VetCert | Checklist; filter by set-aside codes only |
| WW company daily pull at 1k/day | WW (or product entity) entity-associated key / system account | Ops concern, not end-user |
4) Feasibility: daily-pull + cache pipeline¶
4.1 Go / no-go matrix¶
| Claim | Verdict | Notes |
|---|---|---|
| Pure JSON discovery API exists (no Playwright for core list) | GO | Official v2 search |
| Daily refresh of active opportunity universe is official intent | GO | Active notices updated daily; Data Services + API |
| Build daily-pull + cache on basic 10 req/day key alone | NO-GO (as primary production design) | Pagination + description burn |
| Build daily-pull + cache on entity-tier ~1k/day key and/or Data Services bulk | GO | Matches sibling USAJOBS bulk+search pattern |
| Filter by SDVOSB / small business / NAICS / PoP | GO | First-class query params + response fields |
| Full notice body in list response | NO (gap) | Description is secondary URL + key |
status filter for active-only |
CONDITIONAL | Marked Coming Soon — use active field in response + date windows until confirmed live |
| Multi-tenant share of one individual API key | NO-GO (ToS) | Individual keys must not be shared; use system/entity model |
| User “win likelihood %” / composite bid score | NO-GO | Explicit ticket ban |
| Registration is “easy / same week for everyone” | CONDITIONAL / unknown | Official up to 10 business days; validation failures unknown; VetCert separate and variable |
| Target user can realistically become bid-ready | CONDITIONAL-GO | Path is free and real; multi-week process (SAM + bank/EFT + optional VetCert) is honest framing |
4.2 Suggested architecture (P3+, non-binding)¶
Daily active universe -> SAM Data Services extracts (preferred bulk) and/or
Opportunities API with postedFrom/To windows + ptype filters
Enrich on demand -> noticedesc?noticeid=…&api_key=… (budgeted)
Filter store -> setAsideCode, naicsCode, state, responseDeadLine, notice type
User UX -> Browse/cache + explicit filters; deep-link uiLink / sam.gov
Bid path -> External (SAM + agency instructions); WW checklists only
Never -> Scraping, shared individual keys, win-score oracles
Mirror USAJOBS pattern from WW-78/WW-81: bulk/cache for corpus, live API for freshness slices, honest connect/onboarding copy, no first-run wall that requires the user to already be SAM-registered just to browse.
4.3 Honest product language (recommended)¶
Do claim:
- Free public federal contract opportunity data via official SAM.gov APIs / Data Services.
- Filters for small business and SDVOSB/VOSB set-aside codes, NAICS, location, notice type.
- Link-out to the official notice on SAM.gov.
Do not claim:
- “You’re eligible for this set-aside.”
- “High win probability” / any bid score.
- “Register in SAM in minutes and start winning contracts.”
- Instant or guaranteed VetCert timelines.
5) Open questions¶
- Numeric rate limit confirmation for Opportunities specifically — FSD KB0017604 / current System Account guide vs Entity API table; any hourly caps?
- Data Services auth and automation — Can active Contract Opportunities extracts be fetched unattended without a browser session? Exact file naming, retention, column parity with API fields (especially set-aside + NAICS)?
- Description endpoint cost — Rate limit accounting: one noticedesc per notice; HTML vs plain; failure modes when “Description not found.”
- Multi-value filters — Can
ptypeortypeOfSetAsidebe repeated (OpenAPI suggests multi forptype)? Confirm OR vs AND semantics live. - Non-federal system account — Approval friction for a commercial desktop product; required IP allowlists; whether 1k/day is enough at scale.
- ToS for redistributing public opportunity fields inside a commercial app — Public API data
- “share data publicly only from public APIs” language; legal read for multi-user cache display (display vs bulk resale).
- Sole-prop validation failure rates — How often home-address / legal-name mismatches stall the “up to 10 business days” path (user research, not inventable).
- VetCert current median time — Re-measure after SBA’s Nov 2025 backlog claim; don’t freeze pitch on 12 days or 90 days without a dated check.
- VOSB (
VSA/VSS) scope — API table says VA-specific; confirm whether those codes appear only on VA notices in live data. statusparameter GA date — When “Coming Soon” becomes real.- Attachment download auth — Do
resourceLinkswork without key / with key / session? - WorkWingman entity registration — Does the company already have an active SAM entity for the 1k/day tier, or is that an ops dependency before P3 build?
6) Sources fetched¶
| URL | Role |
|---|---|
| https://open.gsa.gov/api/get-opportunities-public-api/ | Official Opportunities v2 endpoints, auth, params, response fields, set-aside table, examples, Data Services pointers, OpenAPI link |
| https://open.gsa.gov/api/entity-api/ | Public API key flow; documented numeric rate-limit table (10 / 1k / 10k tiers) |
| https://sam.gov/entity-registration | UEI-only vs full registration; free path; Login.gov; up to 10 business days active |
| https://sam.gov/about/terms-of-use | No scraping; individual key non-sharing; 90-day key rotation; public API redistribution caveat |
| https://sam.gov/sites/default/files/2024-11/entity-checklist.pdf | Entity registration checklist (structure includes sole proprietorship) |
| https://www.fsd.gov/gsafsd_sp?id=kb_article_view&sysparm_article=KB0017604 | Official API rate-limit KB (page shell fetched; confirm body in browser when ops locks numbers) |
| https://www.fsd.gov/gsafsd_sp?id=kb_article_view&sysparm_article=KB0035680 | System Account + individual API key user guide (referenced) |
| https://veterans.certify.sba.gov/ | SBA VetCert entry for VOSB/SDVOSB |
| https://www.sba.gov/article/2025/11/11/sba-clears-vetcert-program-backlog-put-veteran-entrepreneurs-first | SBA claim: backlog clear, ~12-day average processing as of 2025-11-11 |
| https://www.sba.gov/federal-contracting/contracting-assistance-programs/veteran-contracting-assistance-programs | Veteran contracting assistance overview (program context) |
| System Account User Guide PDFs (GSA / DoD toolbox mirrors) | Cross-check of 10 vs 1,000 vs 10,000 daily tiers |
Secondary (context only — not primary evidence for limits or legal claims): third-party SAM API writeups (govconapi, govtrove, etc.) consistent with 10/1k/10k but must not override official docs where they disagree.
7) Verdict for pitch / P3 planning¶
| Claim | Status |
|---|---|
| “SAM.gov contract opportunities as a pipeline is real” | Supported — official public JSON search API + daily active data |
| “Cheap / no scraping” | Supported — REST + optional free Data Services extracts; keys free |
| “We can daily-pull and cache” | CONDITIONAL-GO — needs entity-tier (or system) quota and/or bulk extracts; not on 10/day basic alone |
| “We can narrow to small / SDVOSB / VA VOSB + NAICS” | Supported at filter/chip layer |
| “Users are bid-ready after a quick signup” | Unsupported — full SAM registration up to ~10 business days (official), VetCert separate and variable |
| “We can show win odds / bid scores” | NO-GO — banned |
| “Individual going independent can register” | Realistic with friction — free official path; sole prop supported; do not overstate ease |
Spike outcome: CONDITIONAL-GO for a P3 daily-pull + cache contractor-opportunity pipeline for WorkWingman, contingent on (1) entity-tier or system API access and/or Data Services bulk automation, (2) ToS-safe key and redistribution model, and (3) product discipline: filters and facts only, deep-link to SAM.gov, honest multi-week registration/certification checklists — no win-likelihood product.
Unblocks design of a later P3 build spike; does not authorize bid-scoring features.