API & MCP reference
Reconmark's data - live opportunities, recompetes, agencies, companies, contract vehicles, and your own pipeline - is available as a read-only REST API and as an MCP server, so you can pull it into scripts, spreadsheets, or an LLM agent. Both surfaces share one auth mechanism (an API key) and one rate limit.
Auth
Every request - REST or MCP - authenticates with an API key as a bearer token:
Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXCreate a key from Settings → API keys. The full secret is shown exactly once, at creation time - Reconmark stores only a hash, so if you lose it you'll need to revoke it and create a new one. API access is a paid-plan feature.
A missing or invalid key returns 401 with error.code = "invalid_api_key". A key that's over its rate limit returns 429 - see Rate limits.
Envelope & errors
Every list endpoint returns data plus a meta pagination block:
{
"data": [ { "id": "SAM-2026-00123", "title": "IT Support Services", ... } ],
"meta": { "page": 1, "pageSize": 10, "total": 342, "totalPages": 35 }
}Single-resource endpoints (e.g. GET /opportunities/{id}) return just data, no meta. Every error - on any 4xx/5xx, from any endpoint - has the same shape, never a bare string:
{ "error": { "code": "rate_limited", "message": "Rate limit exceeded. Retry after 12 seconds." } }| code | status | meaning |
|---|---|---|
| invalid_api_key | 401 | Missing/malformed Authorization header, or the secret doesn't match any non-revoked key. |
| invalid_request | 400 | Query params failed validation; message plus, where relevant, an issues array. |
| not_found | 404 | The requested resource id doesn't exist. |
| rate_limited | 429 | Per-key per-minute limit exceeded. Retry-After header is set. |
| not_implemented | 501 | Spec'd but not-yet-built endpoint - an honest placeholder, never a fake empty success. |
| internal_error | 500 | Unhandled server error, logged server-side. |
Rate limits
Every key has a per-minute limit - 60 requests/min by default, shown per-key in Settings. Every response carries the current state:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1751500860X-RateLimit-Resetis unix seconds for the start of the next window. When you're over the limit you get 429 plus a Retry-After header (seconds). The limit is a fixed one-minute window shared across REST and MCP - calling a tool over MCP counts against the same budget as calling the equivalent REST route.
Endpoints
All routes are under /api/v1, read-only, paginated with page (default 1) and pageSize (default 20, max 100).
/api/v1/opportunitiesSearch live opportunities (RFPs, grants, sources-sought, etc). Same filters as the dashboard's opportunity table.
| naics | 2-6 digit NAICS prefix |
| agency | Agency acronym, e.g. GSA |
| setAside | Set-aside code, e.g. 8A, WOSB, SDVOSB |
| state | Place-of-performance 2-letter state |
| city | Place-of-performance city (partial match) |
| type | Notice type, e.g. RFP, GRANT, Sources Sought |
| q | Free-text search |
| f | Structured filter, repeatable: field:op:value |
| sort / dir | title | type | agency | closes | posted | value, asc | desc |
| page / pageSize | 1-based page, max pageSize 100 (default 20) |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/opportunities?naics=541512&setAside=8A&sort=closes&dir=asc&pageSize=10"/api/v1/opportunities/{id}Full detail for one opportunity by notice id, including documents and Q&A.
| id | The opportunity's notice_id (path segment) |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/opportunities/cd997119e32f4adfbcfc2dfbb6f2812a"/api/v1/recompetesContracts with an expiring incumbent in a time window - what's coming up for rebid.
| months | Expiring-within window, 3-24 (default 18) |
| naics / agency / setAside | Same as opportunities |
| minValue | Minimum contract value |
| q | Free-text search |
| sort | ends | value |
| page / pageSize | Pagination |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/recompetes?months=12&naics=541512&sort=ends"/api/v1/agenciesAgency directory: acronym, name, active opportunity counts.
| q | Free-text search |
| sort / dir | department | agencyComponent | agencyType | activeSolicitationsCount | totalAwardedYtd |
| page / pageSize | Pagination |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/agencies?sort=activeSolicitationsCount&dir=desc"/api/v1/agencies/{code}Agency-intel summary: department, component, active solicitations, YTD awards, top NAICS.
| code | agencies.agency_code (path segment) |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/agencies/097.97AS"/api/v1/companiesSearch government contractors by name, UEI, or location, ranked by total obligated.
| q | Search legal name, UEI, or city |
| sort / dir | legal_name | total_obligated |
| page / pageSize | Pagination |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/companies?q=lockheed"/api/v1/companies/{uei}UEI-keyed company profile: certifications, NAICS/PSC codes, and the last 20 awards.
| uei | The company's UEI (path segment) |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/companies/G4KDGE4JFFK7"/api/v1/vehiclesContract-vehicle / IDIQ directory: ceiling, IDC type, ordering activity, expiration.
| q / naics / agency | Search, NAICS prefix, awarding agency (substring) |
| idcType | IDC type filter |
| minCeiling | Minimum ceiling value |
| expiringWithinMonths | Ordering-window filter, 1-60 months |
| sort | ceiling | lastDateToOrder | obligated | childAwardCount |
| page / pageSize | Pagination |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/vehicles?naics=541512&sort=ceiling"/api/v1/vehicles/{piid}Vehicle profile: holders, ceiling, task-order flow by fiscal year, top ordering agencies.
| piid | The vehicle's PIID (path segment) |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/vehicles/80JSC023DA004"/api/v1/pipelineThe calling key's own user's pursuit pipeline (bid/no-bid tracking). Identity-bound - resolved from the key, not a public/shared resource.
| status | qualifying | bidding | submitted | won | lost | no_bid |
curl -H "Authorization: Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
"https://reconmark.io/api/v1/pipeline?status=bidding"MCP setup
Reconmark also exposes an MCP server at /api/mcp (Streamable HTTP transport) with five tools that wrap the same query functions as the REST API above - no separate data path, same API key, same rate limit.
{
"mcpServers": {
"reconmark": {
"url": "https://reconmark.io/api/mcp",
"headers": { "Authorization": "Bearer rm_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
}
}
}That's Claude Desktop's remote-MCP config shape - other Streamable HTTP clients use the same URL + header. Reconmark doesn't ship a stdio bridge, so a stdio-only client would need its own local proxy.
| tool | what it does |
|---|---|
| search_opportunities | Search opportunities - same filters as the REST list endpoint, trimmed to agent-useful fields. |
| get_opportunity | Full opportunity detail by notice id, including documents and Q&A. |
| list_recompetes | Contracts with an expiring incumbent in a time window - what's coming up for rebid. |
| my_pipeline | Your own pursuit pipeline, resolved from the calling API key's owner - the one identity-bound tool. |
| get_verdict | The transparent 0-100 bid/no-bid score (Go/Watch/Pass) for one opportunity, calibrated from your capability profile and pursuit history. Deterministic - no LLM call happens inside Reconmark for this. |
Changelog & versioning
v1is stable: field names, pagination shape, and error format won't change under you. Breaking changes ship as a new /api/v2 - v1 keeps working alongside it, not pulled out from under existing integrations.