Overview

The GovContractScout API gives you programmatic access to one normalized feed of U.S. government contract opportunities, aggregated from 50+ fragmented state, local, and federal portals into a single clean schema (title, agency, NAICS codes, extracted keywords, due dates, estimated value, and days left). It also exposes our matching algorithm so you can score opportunities against a contractor profile. Access is self-serve: sign up, create a key, and start calling the API immediately. See Authentication below.

Base URL

https://www.govcontractscout.com/api/v1
Version
1.0.0
Format
JSON (application/json)
Authentication
Bearer token

Available Endpoints

MethodEndpointDescription
GET/v1/contractsSearch and filter contracts
GET/v1/contracts/:idGet contract details
GET/v1/statesList states with contract counts
GET/v1/naicsList NAICS codes with contract counts
POST/v1/matchScore a contract against a profile
POST/v1/match/batchScore multiple contracts (max 50)
POST/v1/match/searchSearch contracts with match scoring
GET/v1/usageCheck your API usage

Authentication

All API requests require a valid API key sent via the Authorization header as a Bearer token.

bash
curl -X GET "https://www.govcontractscout.com/api/v1/contracts" \
  -H "Authorization: Bearer gcs_live_xxxxxxxxxxxxxxxxxxxx"

Key Types

PrefixEnvironmentData
gcs_live_ProductionReal contracts

Getting a Key

Keys are self-serve. Create one from your dashboard — no request, no approval, no email. Use a free tier to evaluate the data first.

  1. Sign in and open API Keys
  2. Create a key and accept the API Terms
  3. Copy the key immediately — it is only shown once
Security: Your API key is displayed only once at creation. Store it securely. If compromised, revoke it from your dashboard and create a new one.

Rate Limits

Requests are rate-limited based on your tier and applied per API key. See pricing for the monthly allowances on each paid tier.

TierRequests / MinuteRequests / Month
Free30100
Starter6010,000
Growth30050,000

New free keys get 100 requests/month to evaluate the API — enough to test the shape of the data, too small to harvest it. Paid tiers are self-serve: check out and your key is issued or upgraded instantly. Email api-support@govcontractscout.com if you have questions about an existing key.

Response Headers

Every API response includes rate limit headers so you can track your usage programmatically:

http
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1709500000
ParameterTypeRequiredDescription
X-RateLimit-LimitintegerNoMax requests per minute for your plan
X-RateLimit-RemainingintegerNoRequests remaining in current window
X-RateLimit-ResetintegerNoUnix timestamp when the window resets

Handling 429 Responses

When you exceed the rate limit, the API returns a 429 status with a retry_after value in seconds:

json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Retry after 45 seconds.",
    "retry_after": 45
  }
}

Pricing

Choose the tier that matches your integration volume. Checkout is instant — your key is issued or upgraded automatically. All tiers are a standalone API — separate from a GovContractScout Pro plan — and allow commercial use, but not reselling or redistributing the dataset (see the API terms).

Free

$0/mo

Evaluate the API. No credit card required.

  • 100 requests / month
  • 30 requests / minute
Create a key
Most popular

Starter

$99/mo

For a production integration.

  • 10,000 requests / month
  • 60 requests / minute
  • Instant access on checkout

Growth

$199/mo

Higher volume, higher rate limit.

  • 50,000 requests / month
  • 300 requests / minute
  • Instant access on checkout

Need more than 50k requests/month, or want an MCP / agent integration? Talk to us about an enterprise plan.

Error Handling

The API uses standard HTTP status codes and returns consistent error objects. All errors follow this format:

json
{
  "error": {
    "code": "error_code",
    "message": "Human-readable description",
    "param": "field_name",
    "doc_url": "https://scout.govbidportals.com/docs/api#errors/error_code"
  }
}

Error Codes

CodeHTTP StatusDescription
invalid_api_key401API key is missing, invalid, or revoked
rate_limit_exceeded429Too many requests, retry after the specified delay
monthly_limit_exceeded429Monthly request quota reached; resets at the start of next month or upgrade your plan
invalid_parameter400A query parameter or body field has an invalid value
missing_parameter400A required parameter was not provided
resource_not_found404The requested contract or resource does not exist
payload_too_large413Request body too large (max 64 KB) — thrown by the match, batch, and search endpoints
validation_error422Request body failed validation (details array included)
usage_check_failed503Could not verify request usage right now — fail-closed, retry shortly
server_error500Internal server error

Validation Errors

When request body validation fails, the response includes a details array with per-field errors:

json
{
  "error": {
    "code": "validation_error",
    "message": "Request body validation failed",
    "details": [
      { "field": "profile.naics_codes", "message": "Must be an array of strings" },
      { "field": "profile.service_areas", "message": "Required field missing" }
    ],
    "doc_url": "https://docs.govcontractscout.com/errors/validation_error"
  }
}

List Contracts

GET/v1/contracts

Search and filter the contract database. Returns paginated results without the full description field (use the detail endpoint for that).

Query Parameters

ParameterTypeRequiredDescription
statestringNoSingle state filter, 2-letter code (e.g., "CA")
statesstringNoComma-separated state codes (e.g., "CA,TX,NY")
naicsstringNoNAICS code or prefix (e.g., "541512" or "541")
naics_codesstringNoComma-separated exact NAICS codes
min_valueintegerNoMinimum estimated value in dollars
max_valueintegerNoMaximum estimated value in dollars
keywordstringNoKeyword search on contract title
agencystringNoAgency name, partial match (case-insensitive)
due_afterstringNoISO 8601 date, contracts due after this date
due_beforestringNoISO 8601 date, contracts due before this date
posted_afterstringNoISO 8601 date, contracts posted after this date
statusstringNo"active" (default), "expired", or "all"
sortstringNo"due_date", "posted_date", "value", or "title"
orderstringNo"asc" or "desc" (default)
pageintegerNoPage number (default: 1, max: 20). Use filters to narrow to specific contracts rather than paging deep.
per_pageintegerNoResults per page (default: 20, max: 100)

Example

bash
curl -X GET "https://www.govcontractscout.com/api/v1/contracts?states=CA,TX&naics=541512&min_value=100000&status=active" \
  -H "Authorization: Bearer gcs_live_xxxx"

Pagination

The list endpoint returns up to 100 contracts per page. To pull a set of contracts, page through with per_page=100 and increment page (max 20). Do NOT fire one request per contract in parallel - that burns your rate limit and returns 429s. One page of 100 is one request, not 100.

python
import time
import requests

API = "https://www.govcontractscout.com/api/v1/contracts"
HEADERS = {"Authorization": "Bearer gcs_live_xxxx"}

all_contracts = []
page = 1
while page <= 20:
    r = requests.get(
        API,
        headers=HEADERS,
        params={"per_page": 100, "page": page, "status": "active"},
    )
    if r.status_code == 429:
        # Respect the rate limit: wait for the window to reset, then retry.
        retry_after = int(r.headers.get("Retry-After", "60"))
        time.sleep(retry_after)
        continue
    r.raise_for_status()
    data = r.json()
    all_contracts.extend(data["data"])
    if page >= data["meta"]["total_pages"]:
        break
    page += 1
    time.sleep(1)  # stay well under the per-minute rate limit

print(f"Fetched {len(all_contracts)} contracts")

Response

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "IT Infrastructure Modernization",
      "contract_number": "RFP-2026-0142",
      "state": "CA",
      "agency": "California Department of Technology",
      "location": "Sacramento, CA",
      "posting_date": "2026-02-15T00:00:00Z",
      "due_date": "2026-03-30T17:00:00Z",
      "estimated_value": 500000,
      "naics_codes": ["541512", "541519"],
      "keywords": ["cloud", "migration", "aws", "security"],
      "status": "active",
      "days_until_due": 27,
      "has_attachments": true,
      "created_at": "2026-02-15T08:30:00Z"
    }
  ],
  "meta": {
    "total": 1547,
    "page": 1,
    "per_page": 20,
    "total_pages": 78
  }
}

Get Contract

GET/v1/contracts/:id

Get full details for a single contract, including the full description and updated_at timestamp.

Path Parameters

ParameterTypeRequiredDescription
idstring (UUID)YesContract UUID

Example

bash
curl -X GET "https://www.govcontractscout.com/api/v1/contracts/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer gcs_live_xxxx"

Response

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "IT Infrastructure Modernization",
    "contract_number": "RFP-2026-0142",
    "state": "CA",
    "agency": "California Department of Technology",
    "location": "Sacramento, CA",
    "posting_date": "2026-02-15T00:00:00Z",
    "due_date": "2026-03-30T17:00:00Z",
    "estimated_value": 500000,
    "naics_codes": ["541512", "541519"],
    "keywords": ["cloud", "migration", "aws", "security"],
    "description": "The California Department of Technology (CDT) is seeking qualified vendors...",
    "status": "active",
    "days_until_due": 27,
    "source_url": "https://caleprocure.ca.gov/event/12345",
    "pdf_urls": [
      "https://example.gov/scout/RFP-2026-0142-addendum1.pdf"
    ],
    "has_attachments": true,
    "created_at": "2026-02-15T08:30:00Z",
    "updated_at": "2026-02-15T08:30:00Z"
  }
}

source_url is the original procurement-page link (e.g. the caleprocure event page) — use it to send an end user to the actual solicitation. It is returned on the detail endpoint only, on all tiers. Contracts sourced via BidNet aggregation return null here — we do not link users into third-party aggregator platforms. pdf_urls holds the solicitation document links (PDF, DOCX, XLS) for contracts where the source portal serves them publicly; it is gated to paid plans (Starter, Growth, Enterprise) — free/evaluation keys receive an empty array but still get has_attachments.

List States

GET/v1/states

Get a list of supported U.S. states with the number of currently active contracts in each.

Example

bash
curl -X GET "https://www.govcontractscout.com/api/v1/states" \
  -H "Authorization: Bearer gcs_live_xxxx"

Response

json
{
  "data": [
    { "code": "CA", "name": "California", "active_contracts": 2341 },
    { "code": "FL", "name": "Florida", "active_contracts": 1234 },
    { "code": "NY", "name": "New York", "active_contracts": 1543 },
    { "code": "TX", "name": "Texas", "active_contracts": 1876 }
  ]
}

List NAICS Codes

GET/v1/naics

Get NAICS codes used in the contract database, with active contract counts. Optionally filter by code prefix or search by name.

Query Parameters

ParameterTypeRequiredDescription
prefixstringNoFilter by NAICS code prefix, 2-6 digits (e.g., "541")
searchstringNoSearch by name, case-insensitive (e.g., "engineering")

Example

bash
curl -X GET "https://www.govcontractscout.com/api/v1/naics?prefix=541" \
  -H "Authorization: Bearer gcs_live_xxxx"

Response

json
{
  "data": [
    { "code": "541330", "name": "Engineering Services", "active_contracts": 892 },
    { "code": "541512", "name": "Computer Systems Design Services", "active_contracts": 654 },
    { "code": "541519", "name": "Other Computer Related Services", "active_contracts": 432 },
    { "code": "541611", "name": "Administrative Management Consulting", "active_contracts": 387 }
  ]
}

Score Contract

POST/v1/match

Calculate a match score for a single contract against your contractor profile. Uses a 5-factor algorithm: NAICS codes (30%), keywords/skills (25%), budget fit (20%), location (15%), and timeline (10%).

Request Body

ParameterTypeRequiredDescription
contract_idstring (UUID)YesThe contract to score
profile.naics_codesstring[]YesYour NAICS codes (max 5)
profile.primary_skillsstring[]YesYour core competencies
profile.secondary_skillsstring[]NoAdditional skills
profile.service_areasstring[]YesStates you can work in (2-letter codes)
profile.headquarters_statestringYesYour HQ state (2-letter code)
profile.min_contract_valueintegerNoMinimum contract value you would bid on
profile.max_contract_valueintegerNoMaximum contract value you can handle
profile.min_days_to_deadlineintegerNoMinimum days needed to prepare a bid (default: 30)
profile.remote_capablebooleanNoCan perform work remotely (default: false)

Example

bash
curl -X POST "https://www.govcontractscout.com/api/v1/match" \
  -H "Authorization: Bearer gcs_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "contract_id": "550e8400-e29b-41d4-a716-446655440000",
    "profile": {
      "naics_codes": ["541512", "541519"],
      "primary_skills": ["cloud migration", "aws", "devops"],
      "secondary_skills": ["security", "terraform"],
      "service_areas": ["CA", "NV", "OR"],
      "headquarters_state": "CA",
      "min_contract_value": 50000,
      "max_contract_value": 1000000,
      "remote_capable": true
    }
  }'

Response

json
{
  "data": {
    "contract_id": "550e8400-e29b-41d4-a716-446655440000",
    "match_score": 87,
    "match_grade": "excellent",
    "breakdown": {
      "naics_score": 100,
      "naics_weight": 0.30,
      "budget_score": 100,
      "budget_weight": 0.20,
      "location_score": 100,
      "location_weight": 0.15,
      "keywords_score": 72,
      "keywords_weight": 0.25,
      "timeline_score": 80,
      "timeline_weight": 0.10
    },
    "match_reasons": [
      "Strong industry match - NAICS codes align perfectly",
      "Contract value ($500,000) fits your budget range ($50K-$1M)",
      "Located in your service area (California)",
      "Your skills match: cloud, migration, aws, devops"
    ]
  }
}

Match Grades

GradeScore RangeMeaning
excellent80 – 100Strong fit, prioritize this contract
good60 – 79Good fit, worth reviewing
okay40 – 59Moderate fit, review if time permits
poor0 – 39Weak fit, likely skip

Batch Score

POST/v1/match/batch

Score multiple contracts against a profile in a single request. Maximum 50 contracts per request. Non-existent contract IDs are silently skipped.

Request Body

ParameterTypeRequiredDescription
contract_idsstring[] (UUIDs)YesArray of contract UUIDs to score (max 50)
profileobjectYesContractor profile (same shape as /match endpoint)

Example

bash
curl -X POST "https://www.govcontractscout.com/api/v1/match/batch" \
  -H "Authorization: Bearer gcs_live_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "contract_ids": [
      "550e8400-e29b-41d4-a716-446655440000",
      "550e8400-e29b-41d4-a716-446655440001",
      "550e8400-e29b-41d4-a716-446655440002"
    ],
    "profile": {
      "naics_codes": ["541512"],
      "primary_skills": ["cloud", "aws"],
      "service_areas": ["CA"],
      "headquarters_state": "CA"
    }
  }'

Response

json
{
  "data": [
    {
      "contract_id": "550e8400-e29b-41d4-a716-446655440000",
      "match_score": 87,
      "match_grade": "excellent",
      "breakdown": { ... },
      "match_reasons": [ ... ]
    },
    {
      "contract_id": "550e8400-e29b-41d4-a716-446655440001",
      "match_score": 72,
      "match_grade": "good",
      "breakdown": { ... },
      "match_reasons": [ ... ]
    }
  ]
}

Win Likelihood

POST/v1/win-likelihood

Estimate the probability (0-100) that your company profile wins a specific contract, based on the historical award archetype that wins in its category plus incumbent/recompete intel. A paid-tier (Starter+) feature.

Request Body

ParameterTypeRequiredDescription
contract_idstring (uuid)YesThe contract to score
profileobjectYesContractor profile (same base shape as /match)
profile.company_namestringNoYour company name - used to detect if you are the incumbent on a recompete
profile.past_award_amountnumberNoYour typical past award size in USD (compared against the incumbent's last award)
profile.past_agenciesstring[]NoAgencies you have worked with - matched against the awarding agency
profile.years_in_businessnumberNoYears in business (track-record signal)
profile.past_awards_countnumberNoNumber of past awards (track-record signal)

Response

json
{
  "data": {
    "contract_id": "43308678-...",
    "win_likelihood": 52,
    "grade": "okay",
    "reasons": [
      "Best-fit archetype: Transportation & Logistics (791 past awards, typically $125-$6,329,308).",
      "You are the incumbent (MUSE TRUCKING, INC.) on this recompete - incumbents hold a strong edge on renewals.",
      "Your past awards ($300,000) are comparable to the incumbent's last award ($300,000) - a credible challenger."
    ],
    "archetype": {
      "key": "it-software-services",
      "name": "IT & Software Services",
      "size_band": "micro",
      "typical_amount_min": 0,
      "typical_amount_max": 7468956,
      "typical_agency_types": ["health", "technology", "state-local-agency"],
      "states": ["NY", "TX", "NH"],
      "award_count": 1636
    },
    "intel": {
      "likely_incumbent": "MUSE TRUCKING, INC.",
      "last_award_amount": 300000,
      "awarding_agency": "Department of Agriculture",
      "is_recompete": true,
      "competitor_count": 13,
      "incumbent_matches_user": true
    },
    "breakdown": { }
  }
}

Intel signals (the non-obvious part): you are the incumbent (+14), a challenger on a recompete (-10, +6 if your past-award size is comparable), thin vs crowded competition (+/-6), and past agency relationships (+5).

Archetypes

GET/v1/archetypes

List the winning-business archetypes derived from historical government contract awards. Each describes who wins what - the derived-data layer. A paid-tier (Starter+) feature.

Response

json
{
  "data": [
    {
      "key": "it-software-services",
      "name": "IT & Software Services",
      "category": "Technology",
      "sector": ["54", "51"],
      "description": "Software development, IT systems design, data processing... wins technology solicitations."
    }
  ],
  "meta": { "count": 16 }
}

API Usage

GET/v1/usage

Check your current API usage statistics, including requests used, remaining quota, and rate limit for the current billing period.

Example

bash
curl -X GET "https://www.govcontractscout.com/api/v1/usage" \
  -H "Authorization: Bearer gcs_live_xxxx"

Response

json
{
  "data": {
    "plan": "starter",
    "period_start": "2026-03-01",
    "period_end": "2026-03-31",
    "requests_used": 4521,
    "requests_limit": 10000,
    "requests_remaining": 5479,
    "rate_limit_per_minute": 60
  }
}

Agent / MCP

The GovContractScout data and derived insights are callable by AI agents through an MCP (Model Context Protocol) server. Agents can search contracts, score fit, and estimate win likelihood — without writing raw HTTP code.

Tools

ToolBackendPurpose
search_contractsGET /v1/contractsSearch/filter contracts
get_contractGET /v1/contracts/:idContract detail
search_naicsGET /v1/naicsNAICS lookup
get_statesGET /v1/statesState coverage
score_contractPOST /v1/match5-factor match score
win_likelihoodPOST /v1/win-likelihoodWin probability vs the historical award archetype (derived data, paid)
archetypesGET /v1/archetypesList winning-business archetypes — who wins what (paid)

Connect (Claude Code)

bash
claude mcp add govcontractscout -- node /path/to/mcp-server/dist/index.js
claude mcp set-env govcontractscout GCS_API_KEY gcs_live_YOUR_KEY

The server requires a gcs_live_... API key (free or paid). Search, match, and lookup tools work on free; the derived-data tools (win_likelihood, archetypes) require a paid (Starter+) tier. An example agent ask: "Find Texas IT services contracts due this month, score the top one against our profile (NAICS 541511, TX), and estimate our win likelihood."

FAQ

How do I link an end user to the actual solicitation?

Use source_url from the contract detail endpoint (GET /api/v1/contracts/:id). It is the original procurement-page link, available on all tiers. The solicitation documents themselves are in pdf_urls (paid tiers).

How do I pull a large set of contracts without hitting rate limits?

Use pagination: per_page=100 and increment page (max 20). One page of 100 is one request, not 100. Do not fire one request per contract in parallel - that burns your rate limit and returns 429s. See the Pagination section for a full example.

Why am I getting 429 (rate limit exceeded)?

429 means you exceeded your per-minute rate limit. Free is 30/min, Starter 60/min, Growth 300/min. Respect the Retry-After header on the 429 response, or add a small delay between requests. If you are on a paid tier, the limit applies across all your keys (per-user), so a free key you created earlier does not throttle you.

What is the difference between the free and paid tiers?

Free: 100 requests/month, 30/min, all read endpoints + match scoring, no pdf_urls. Starter ($99/mo): 10,000 requests/month, 60/min, plus pdf_urls (solicitation documents). Growth ($199/mo): 50,000 requests/month, 300/min. See Pricing.

Can I use the API for a commercial product?

Yes - commercial use is allowed, including embedding the data in your own product (the intended use). You may not resell or redistribute the raw dataset as a competing data product. See the API terms.

How do I create an API key?

Sign in, go to the API keys page, and create a key. You will need to name it, describe what it is for, and accept the API terms. Free keys are instant; paid tiers are self-serve on checkout.

How fresh is the data?

Contracts are synced daily from the source portals. The detail endpoint returns updated_at so you can track changes.

Need help?

Contact us at api-support@govcontractscout.com

Get started

Free keys are self-serve — sign up and create one instantly. Paid tiers are instant too: check out and your key is issued or upgraded immediately.

Pricing

Free (100 req/mo) to test, Starter ($99/mo, 10,000 req/mo) and Growth ($199/mo, 50,000 req/mo) for production. Instant access on checkout. This is a standalone API, separate from a GovContractScout Pro plan. Commercial use is allowed, but reselling or redistributing the dataset is not, see the API terms.

GovContractScout API v1.0.0