Create a key, run one request, inspect the response.
curl -s "https://api.boringdataplatform.com/v1/opportunities" \
--get \
--data-urlencode "source=sam_current" \
--data-urlencode "limit=1" \
-H "Authorization: Bearer $BORING_API_KEY"{
"data": [{
"recordId": "00000000-0000-4000-8000-000000000001",
"summary": {
"title": "Enterprise IT Support Services",
"agencyName": "Department of Defense",
"opportunityStatus": "active"
},
"documents": {
"hasExtractedText": true,
"attachmentCount": 3
}
}],
"page": { "limit": 1, "nextCursor": null }
}Introduction
The Boring Data Platform API serves federal procurement data as one normalized API contract. SAM.gov, DIBBS, USAspending, and SAM.gov source-backed feeds return predictable data responses, cursor page objects where needed, searchable attachment evidence, and a consistent top-level error object for failures.
This page is your entry point. Start with Authentication to grab a key, skim Rate limits so you know your budget, then try the first REST call below. If you'd rather use an agent, use the MCP agents guide.
/v1/opportunities?source=sam_current&status=active&sort_by=closing&limit=5curl "https://api.boringdataplatform.com/v1/opportunities" \
--get \
--data-urlencode "source=sam_current" \
--data-urlencode "status=active" \
--data-urlencode "sort_by=closing" \
--data-urlencode "limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"Authentication
Every request to /v1/* requires a bearer token in the Authorization header or an x-api-key header. API keys are generated from the console and use the strata_live_… prefix. They never expire until revoked.
Rate limits
Per-key sliding-window limits are shared across REST and MCP. A tool call on the MCP surface costs one request against the same monthly budget. REST responses include x-strata-rate-limit-limit, x-strata-rate-limit-remaining, and x-strata-rate-limit-reset as a Unix timestamp; 429 responses from the per-minute limiter also include Retry-After. A 429 body includes error.reason as rate_limit_minute or quota_monthly.
| Name | Type | Description |
|---|---|---|
| Sandbox | 60 rpm | Hard cap at 5,000 requests/month. |
| Starter | 600 rpm | Hard cap at 10,000 requests/month. |
| Growth | 600 rpm | Hard cap at 100,000 requests/month. |
| Developer | 600 rpm | Hard cap at 500,000 requests/month. |
GET /v1/opportunities
/v1/opportunities/v1/opportunities/{recordId}/v1/opportunities/{recordId}/documents/v1/opportunities/{recordId}/history/v1/opportunities/{recordId}/awards/v1/opportunities/{recordId}/incumbents/v1/opportunities/{recordId}/buyer-profileCanonical opportunity threads. The list endpoint defaults to live/current opportunity sources and excludes the SAM archive. Filter with source=sam_current, source=dibbs, or source=sam_archive; then fetch a detail record by recordId to get summary, documents, history, and analysis in one response. Use posted_after and posted_before for inclusive posted-date windows; bare dates expand to UTC day boundaries. Use sort_by=closing&status=active&closing_before=YYYY-MM-DD for opportunities closing by a computed date. Use agency_code for rows whose office path maps to Federal Hierarchy agency/sub-tier names; unmapped rows are excluded while the filter is set.
| Name | Type | Description |
|---|---|---|
| source | enum | Optional. Filter to sam_current, sam_archive, or dibbs. Omitted returns live/current opportunity sources and excludes SAM archive rows. |
| q | string | Optional free-text search across opportunity summaries. |
| document_query | string | Optional extracted-attachment-text search. Matching rows include compact documentMatches evidence. |
| posted_after | date | date-time | Inclusive posted-at lower bound. Bare dates use 00:00:00.000Z. |
| posted_before | date | date-time | Inclusive posted-at upper bound. Bare dates use 23:59:59.999Z. |
| closing_before | date | date-time | Inclusive response-deadline upper bound. Rows without closeAt are excluded. |
| agency_code | string | Federal Hierarchy agency code. Department codes ending in 00 also match mapped sub-tier rows; unmapped office paths are excluded. |
| limit | integer | Cursor-page size. Values between 1 and 100. |
/v1/opportunities?source=dibbs&limit=10curl "https://api.boringdataplatform.com/v1/opportunities?source=dibbs&limit=10" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": [
{
"recordId": "00000000-0000-4000-8000-000000000002",
"threadKey": "dibbs:SPE4A626U2442",
"summary": {
"sourceName": "dibbs-rfqs-posted-date",
"sourceFamily": "dibbs",
"noticeId": "SPE4A626U2442",
"title": "Screw, Machine",
"agencyName": "DLA Land and Maritime"
},
"documents": {
"hasPackagePage": true,
"hasPdf": true,
"hasExtractedText": true,
"hasTechnicalDocuments": true,
"attachmentCount": 7
}
}
],
"page": { "limit": 10, "nextCursor": null }
}Document Search
/v1/documents/search/v1/opportunities/{recordId}/documents/text/v1/opportunities/{recordId}/documents/search/v1/opportunities/{recordId}/documents/requirementsSearch extracted opportunity attachment text across indexed SAM and DIBBS documents, return bounded OCR text for one opportunity document, or scope the search to one opportunity. Requirement extraction returns structured document evidence for current SAM read-model rows while live lakehouse reads are disabled. Private storage URIs stay hidden; responses return document metadata and evidence snippets. Use document_query on /v1/opportunities when you want the opportunity list itself filtered by attachment text. For the workflow version, read SAM.gov opportunity attachments via API.
| Name | Type | Description |
|---|---|---|
| q | string | Required search query. Values must be 2-200 characters. |
| source | enum | Optional source filter for global document search: sam_current, sam_archive, or dibbs. |
| record_id | uuid | Optional platform recordId filter for global search. |
| thread_key | string | Optional source thread key filter for global search. |
| limit | integer | Cursor-page size. Values between 1 and 100. |
/v1/documents/search?q=delivery%20schedule&source=sam_current&limit=5curl "https://api.boringdataplatform.com/v1/documents/search?q=delivery%20schedule&source=sam_current&limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": [
{
"document": {
"documentId": "sha256:5f2d…",
"fileName": "solicitation.pdf",
"kind": "attachment",
"sourceUrl": "https://sam.gov/..."
},
"opportunity": {
"recordId": "00000000-0000-4000-8000-000000000001",
"threadKey": "sam:W912ABC26R0001",
"title": "Enterprise IT Support Services"
},
"match": {
"score": 2,
"snippet": "Delivery schedule must include...",
"matchedTerms": ["delivery", "schedule"]
}
}
],
"page": { "limit": 5, "nextCursor": null }
}/v1/opportunities/00000000-0000-4000-8000-000000000002/documents/text?max_chars=5000curl "https://api.boringdataplatform.com/v1/opportunities/00000000-0000-4000-8000-000000000002/documents/text?max_chars=5000" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": {
"recordId": "00000000-0000-4000-8000-000000000002",
"documentId": "sha256:5f2d…",
"fileName": "SPE4A626U2442.PDF",
"sourceUrl": "https://www.dibbs.bsm.dla.mil/...",
"pdfUrl": "https://www.dibbs.bsm.dla.mil/...",
"extractedTextLength": 78518,
"returnedTextLength": 5000,
"truncated": true,
"text": "SOLICITATION, OFFER AND AWARD..."
}
}GET /v1/opportunities/{recordId}/related
/v1/opportunities/{recordId}/relatedCross-source relationship evidence. Use this when a SAM posting points to a DIBBS RFQ package, when the same normalized solicitation appears in both systems, or when a workflow needs to show related source records without merging them into one identity.
/v1/opportunities/00000000-0000-4000-8000-000000000001/related?limit=5curl "https://api.boringdataplatform.com/v1/opportunities/00000000-0000-4000-8000-000000000001/related?limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": [
{
"linkId": "sam-dibbs:SPE4A626U2442",
"relationType": "sam_mentions_dibbs_and_exact_match",
"confidence": 0.98,
"direction": "outbound",
"normalizedSolicitationNumber": "SPE4A626U2442",
"evidence": {
"matchedFields": ["solicitation_number", "sam_text_mentions_dibbs"]
},
"relatedOpportunity": {
"recordId": "00000000-0000-4000-8000-000000000002",
"threadKey": "dibbs:SPE4A626U2442",
"sourceFamily": "dibbs",
"title": "Screw, Machine",
"agencyName": "DLA Land and Maritime"
}
}
],
"page": { "limit": 5, "nextCursor": null }
}GET /v1/opportunities/{recordId}/incumbents
/v1/opportunities/{recordId}/incumbentsLikely incumbent vendors for an opportunity. Use this when a capture or pricing workflow needs the vendor that appears to hold the work, the linked award dollars, the current period end date, and recompete status with direct or contextual award evidence.
/v1/opportunities/00000000-0000-4000-8000-000000000001/incumbents?limit=5curl "https://api.boringdataplatform.com/v1/opportunities/00000000-0000-4000-8000-000000000001/incumbents?limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": [
{
"vendorUei": "G9HKMXL5L973",
"vendorName": "OIL STATES INDUSTRIES, INC.",
"linkedAwardCount": 1,
"obligatedAmount": "0.00",
"totalContractValue": null,
"latestAwardDate": null,
"currentEndDate": "2026-03-06",
"daysUntilCurrentEnd": -60,
"recompeteStatus": "expired",
"confidence": 0.99,
"evidence": [
{
"matchRule": "solicitation_identifier_equals_solicitation_number",
"matchedField": "solicitation_identifier",
"confidence": 0.99,
"solicitationNumber": "SPE7M324T4484",
"awardSolicitationIdentifier": "SPE7M324T4484",
"periodOfPerformanceCurrentEndDate": "2026-03-06",
"award": {
"transactionKey": "9700_-NONE-_SPE7M124V3270_P00002_-NONE-_0",
"piid": "SPE7M124V3270",
"vendorName": "OIL STATES INDUSTRIES, INC.",
"obligatedAmount": "0.00"
}
}
]
}
],
"page": { "limit": 5, "nextCursor": null }
}GET /v1/opportunities/{recordId}/buyer-profile
/v1/opportunities/{recordId}/buyer-profileBuyer and office context for one opportunity. Use this when a capture workflow needs contacts, office path, similar postings, and recent award/vendor signals in one response.
/v1/opportunities/00000000-0000-4000-8000-000000000001/buyer-profile?limit=5curl "https://api.boringdataplatform.com/v1/opportunities/00000000-0000-4000-8000-000000000001/buyer-profile?limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"application/json{
"data": {
"opportunity": {
"recordId": "00000000-0000-4000-8000-000000000001",
"solicitationNumber": "SPE7M324T4484",
"agencyName": "Defense Logistics Agency",
"pscCode": "R499"
},
"buyer": {
"agencyName": "Defense Logistics Agency",
"officeName": "DLA Land and Maritime",
"officePathSegments": ["DEPT OF DEFENSE", "DLA Land and Maritime"],
"buyerName": null,
"contacts": [],
"hasBuyerContact": false
},
"naicsCodes": [],
"pscCode": "R499",
"similarOpportunities": [],
"awardSignals": {
"scope": {
"fiscalYearStart": 2024,
"fiscalYearEnd": 2026,
"agencyName": "Defense Logistics Agency",
"pscCode": "R499",
"naicsCodes": []
},
"awardCount": 0,
"obligatedAmount": null,
"totalContractValue": null,
"latestAwardDate": null,
"topVendors": []
},
"evidence": {
"sourceTables": ["opportunity_threads", "opportunity_analysis", "contract_awards"],
"warnings": ["buyer_contact_not_found"]
}
}
}GET /v1/notices
/v1/noticesSource-verbatim notices (the raw record before threading). Use when you need exactly what a source published, not the merged canonical view.
GET /v1/changes
/v1/changesIncremental sync. Cursor-based pagination with updatedSince to resume where you left off. For amendment polling, read tracking SAM.gov amendments with a change feed.
GET /v1/opportunities/analysis
/v1/opportunities/analysisStructured filtering across the canonical opportunity stream. Query by source, sourceFamily, status, category, setAside, contractType, deliveryRegion, naics, office, agency_code, and feature flags (hasExtractedText, hasPdf, hasAward, hasTechnicalDocuments). posted_after and posted_before use the same inclusive UTC date-window semantics as the opportunity list; closing_before excludes rows without a response deadline. Pair with /v1/opportunities/analysis/rollups for aggregated facet counts.
GET /v1/awards
/v1/awardsFederal contract award actions from USAspending.gov. Filter by vendor_uei, awarding_agency_code, naics_code, psc_code, piid, fiscal year, or action-date window. Use /v1/awards/analysis/rollups with group_by set to awarding_agency_code, naics_code, psc_code, or vendor_uei for grouped analytics.
GET /v1/entities
/v1/entities/v1/entities/{uei}SAM.gov entity registrations keyed by UEI. Use the list endpoint for discovery and filtering, then fetch a specific UEI for the latest monthly registration snapshot or a pinned snapshot_month.
| Name | Type | Description |
|---|---|---|
| uei | string | Filter to one Unique Entity ID. |
| cage_code | string | Filter to one CAGE code. |
| registration_status | string | Filter by SAM registration status. |
| primary_naics | string | Filter by primary NAICS code. |
| snapshot_month | YYYY-MM | Pin the monthly SAM registration snapshot. |
GET /v1/entities/{uei}/profile
/v1/entities/{uei}/profileConnected vendor profile for one UEI: latest SAM registration, recent contract awards, agency award rollups, exclusions, and public responsibility/integrity records. Pin registration state with snapshot_month and exclusion/integrity state with snapshot_date.
GET /v1/agencies
/v1/agencies/v1/agencies/{orgId}SAM.gov Federal Hierarchy organizations for department, independent agency, and sub-tier context. Use these rows to resolve agency codes and understand the government hierarchy behind awards and assistance listings.
| Name | Type | Description |
|---|---|---|
| agency_code | string | Match CGAC / agency organization codes. |
| fh_org_type | enum | department-ind-agency, sub-tier, or federal-hierarchy-org. |
| status | string | Filter active/inactive Federal Hierarchy rows. |
| parent_fh_org_id | string | Return children under a parent organization. |
| snapshot_date | YYYY-MM-DD | Pin a historical Federal Hierarchy snapshot. |
/v1/agencies?limit=5curl "https://api.boringdataplatform.com/v1/agencies?limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"GET /v1/assistance-listings
/v1/assistance-listings/v1/assistance-listings/{listingId}SAM.gov Assistance Listings / CFDA federal program reference data. Responses include program descriptions, organization codes, fiscal-year metadata, and opportunistic Federal Hierarchy enrichment when agency codes match.
| Name | Type | Description |
|---|---|---|
| assistance_listing_id | string | Filter to one Assistance Listing / CFDA id. |
| status | string | Filter active or inactive program listings. |
| fiscal_year | integer | Filter by listing fiscal year. |
| department_code | string | Filter by department organization code. |
| agency_code | string | Filter by agency organization code. |
| snapshot_date | YYYY-MM-DD | Pin a historical Assistance Listings snapshot. |
/v1/assistance-listings?limit=5curl "https://api.boringdataplatform.com/v1/assistance-listings?limit=5" \
-H "Authorization: Bearer <YOUR_API_KEY>"Compliance Records
/v1/exclusions/v1/integrity-recordsSearch SAM.gov exclusion records and public Responsibility / Qualification / FAPIIS integrity records directly, or reach them through /v1/entities/{uei}/profile when the user is asking about a specific vendor.
Errors
Every error response contains a top-level error object with a machine-readable code and human message. The rate_limited code covers both the per-minute key limit and the monthly account quota; use error.reason to distinguish rate_limit_minute from quota_monthly. Retry logic on 5xx and 429 is safe; retries on 4xx other than 429 are not.