API Tutorials

From first request to a running contractor-alert workflow. Each tutorial is self-contained with copy-paste code.

01

Quickstart

Create a key and make your first request in under five minutes.

  1. Get a key. For a free key, no account is needed. Select Email me a free key on the API documentation page, or POST to /api/api-keys/free.
  2. For a paid key, sign in and create it on the dashboard API keys page. Name it, describe what it is for, and accept the terms.
  3. Set your key: export GCS_API_KEY=your_key_here
  4. Make the first request:
curl "https://scout.govbidportals.com/api/v1/contracts?states=CA&per_page=5" \
  -H "Authorization: Bearer $GCS_API_KEY"

Result: A JSON response with up to 5 active California contracts, each with id, title, agency, due_date, and NAICS.

馃挕 Use a free key (100 req/mo) to test the shape before you scale.

02

Pagination

Pull large sets of contracts without hitting rate limits.

  1. The list endpoint returns up to 100 contracts per page. Use per_page=100 and increment page (max 20).
  2. Stop when page reaches total_pages from the response meta.
  3. Add a 1s delay between pages to stay under your per-minute limit.
import requests, time

r = requests.get("https://scout.govbidportals.com/api/v1/contracts",
  headers={"Authorization": "Bearer " + API_KEY},
  params={"per_page": 100, "page": page, "status": "active"})
data = r.json()
all_contracts.extend(data["data"])
if page >= data["meta"]["total_pages"]:
    break   # done
page += 1
time.sleep(1)

Result: Every contract matching your filters, one page of 100 at a time.

馃挕 Do NOT fire one request per contract in parallel - that triggers 429s. One page of 100 is one request.

03

Filtering

Narrow the dataset to the contracts you care about.

  1. Filter by state (state or states), NAICS (naics or naics_codes), value (min_value/max_value), keyword, and agency.
  2. Combine filters with & in one request - they are AND-ed together.
  3. Use date filters (due_after, due_before, posted_after) to focus on upcoming work.
curl "https://scout.govbidportals.com/api/v1/contracts?states=CA,NV&naics_codes=541512&min_value=100000&due_after=2026-10-01" \
  -H "Authorization: Bearer $GCS_API_KEY"

Result: Only CA/NV IT-services contracts worth $100k+ due after October.

馃挕 The naics param accepts a 2-6 digit code or prefix - 541 matches all IT-services sectors.

04

Match Scoring

Score a contract against your company profile with the 5-factor engine.

  1. Build a profile: NAICS codes, budget range, service area (states), keywords, and timeline preference.
  2. POST the profile and a contract_id to /api/v1/match.
  3. Read match_score, match_grade, and match_reasons to decide whether to pursue it.
curl -X POST "https://scout.govbidportals.com/api/v1/match" \
  -H "Authorization: Bearer $GCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contract_id": "550e8400-e29b-41d4-a716-446655440000",
    "profile": {
      "naics_codes": ["541512"],
      "min_budget": 50000,
      "max_budget": 5000000,
      "state": "CA",
      "keywords": ["cloud", "migration"]
    }
  }'

Result: A match_score (0-100), grade, and human-readable reasons explaining the score.

馃挕 Use /api/v1/match/batch to score many contracts at once, or /api/v1/match/search to search and score in one call.

05

Link to Solicitations

Send end users to the actual solicitation page and documents.

  1. GET /api/v1/contracts/{id} for a contract's detail.
  2. source_url is the original procurement-page link - send users there.
  3. pdf_urls (paid tiers) are the solicitation documents (RFP, specs).
curl "https://scout.govbidportals.com/api/v1/contracts/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer $GCS_API_KEY"

Result: The detail includes source_url (original page) and pdf_urls (documents) for paid keys.

馃挕 source_url is available on all tiers and is detail-only - fetch it per contract you care about.

06

Build a Contractor Alert

The end-to-end pattern: watch for matching contracts and notify your users.

  1. Run a scheduled job (cron) that queries the list endpoint with your filters.
  2. For each new match, GET its detail to grab source_url (and pdf_urls on paid).
  3. Email your users a link to the solicitation. Respect rate limits with pagination + delays.
# Pseudocode for a nightly alert job
new_contracts = search(filters)           # paginate, compare to last run
for c in new_contracts:
    detail = get_detail(c["id"])          # source_url, pdf_urls
    notify_user(email, detail["source_url"], detail["title"])

Result: Your users get notified the moment a relevant solicitation drops, with a link straight to it.

馃挕 This is the pattern the API was built for - you bring the matching/UX, we supply clean, fresh, normalized data.