BidStream API

Programmatically access government contract opportunities from SAM.gov and state procurement systems. 3,000+ active RFPs updated daily.

Get API Access →

$37/month • 10,000 requests/day • Cancel anytime

Quick Start

Get your first opportunities in 3 steps:

  1. 1

    Sign up and subscribe

    Create an account and subscribe to the API plan ($37/month)

    Sign up here →
  2. 2

    Generate your API key

    Go to your dashboard → API Keys section → Generate Key

    Format: bs_live_xxxxxxxxxxxxx...

  3. 3

    Make your first request

    curl https://bidstream.org/api/v1/opportunities \
      -H "X-API-Key: your_api_key_here" \
      | jq

Authentication

All API requests require authentication via API key. Include your key in one of two ways:

Option 1: X-API-Key header (recommended)

curl https://bidstream.org/api/v1/opportunities \
  -H "X-API-Key: bs_live_your_key_here"

Option 2: Authorization Bearer header

curl https://bidstream.org/api/v1/opportunities \
  -H "Authorization: Bearer bs_live_your_key_here"

Keep your API key secret! Don't commit it to version control or expose it in client-side code.

Rate Limiting

API requests are rate-limited to ensure fair usage:

Per-Minute Limit

100

requests per minute

Daily Limit

10,000

requests per day

Rate Limit Responses

If you exceed the limit, you'll receive a 429 Too Many Requests response:

{
  "error": {
    "message": "Rate limit exceeded: 100 requests per minute",
    "code": "RATE_LIMIT_MINUTE"
  }
}

Check your current usage via the /api/v1/account endpoint.

API Endpoints

GET /api/v1/opportunities

Search and filter government contract opportunities.

Query Parameters

Parameter Type Description
keywordstringSearch in title/description
agencystringFilter by agency name
statestringFilter by state (e.g., CA, TX)
naics_codestringFilter by NAICS code (e.g., 236)
posted_afterdateISO date (e.g., 2026-01-01)
deadline_beforedateISO date
sourcestringFilter by source (sam.gov, california, etc.)
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 20, max: 100)

Example Request

curl "https://bidstream.org/api/v1/opportunities?state=CA&keyword=construction&per_page=10" \
  -H "X-API-Key: bs_live_your_key_here"

Example Response

{
  "data": [
    {
      "id": 12345,
      "source_id": "abc123",
      "source_name": "sam.gov",
      "title": "Road Construction Services",
      "description": "Request for proposals for highway resurfacing...",
      "agency": "California Department of Transportation",
      "posted_date": "2026-02-15T00:00:00.000Z",
      "response_deadline": "2026-03-15T23:59:59.000Z",
      "naics_code": "237310",
      "location_city": "Sacramento",
      "location_state": "CA",
      "source_url": "https://sam.gov/...",
      "created_at": "2026-02-15T08:30:00.000Z"
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 10,
    "total": 1523,
    "total_pages": 153
  }
}

Code Examples

Python

import requests

API_KEY = "bs_live_your_key_here"
BASE_URL = "https://bidstream.org/api/v1"

response = requests.get(
    f"{BASE_URL}/opportunities",
    headers={"X-API-Key": API_KEY},
    params={
        "state": "CA",
        "keyword": "construction",
        "per_page": 10
    }
)

data = response.json()
for opp in data["data"]:
    print(f"{opp['title']} - {opp['agency']}")

JavaScript (Node.js)

const API_KEY = "bs_live_your_key_here";
const BASE_URL = "https://bidstream.org/api/v1";

async function getOpportunities() {
  const params = new URLSearchParams({
    state: "CA",
    keyword: "construction",
    per_page: 10
  });

  const response = await fetch(`${BASE_URL}/opportunities?${params}`, {
    headers: {
      "X-API-Key": API_KEY
    }
  });

  const data = await response.json();
  data.data.forEach(opp => {
    console.log(`${opp.title} - ${opp.agency}`);
  });
}

getOpportunities();
GET /api/v1/opportunities/:id

Get details for a single opportunity by ID.

Example Request

curl "https://bidstream.org/api/v1/opportunities/12345" \
  -H "X-API-Key: bs_live_your_key_here"

Example Response

{
  "data": {
    "id": 12345,
    "source_id": "abc123",
    "source_name": "sam.gov",
    "title": "Road Construction Services",
    "description": "Request for proposals for highway resurfacing...",
    "agency": "California Department of Transportation",
    "posted_date": "2026-02-15T00:00:00.000Z",
    "response_deadline": "2026-03-15T23:59:59.000Z",
    "naics_code": "237310",
    "location_city": "Sacramento",
    "location_state": "CA",
    "source_url": "https://sam.gov/...",
    "created_at": "2026-02-15T08:30:00.000Z"
  }
}
GET /api/v1/matching

Get personalized opportunities matched to your profile (industry, location, keywords).

Query Parameters

Parameter Type Description
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 20, max: 100)
min_scoreintegerMinimum relevance score (0-100)

Example Request

curl "https://bidstream.org/api/v1/matching?min_score=70&per_page=20" \
  -H "X-API-Key: bs_live_your_key_here"

Example Response

{
  "data": [
    {
      "id": 12345,
      "title": "Road Construction Services",
      "description": "...",
      "agency": "California Department of Transportation",
      "posted_date": "2026-02-15T00:00:00.000Z",
      "response_deadline": "2026-03-15T23:59:59.000Z",
      "relevance_score": 85,
      "match_reasons": [
        "Location match: CA",
        "Industry match: 237310 (Highway, Street, and Bridge Construction)",
        "Keyword match: construction"
      ],
      "has_preferences": true
    }
  ],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 142,
    "total_pages": 8
  }
}
GET /api/v1/account

Get your account information, API usage stats, and rate limits.

Example Request

curl "https://bidstream.org/api/v1/account" \
  -H "X-API-Key: bs_live_your_key_here"

Example Response

{
  "data": {
    "account": {
      "email": "user@example.com",
      "company_name": "ACME Corp",
      "industry": "236",
      "location_state": "CA",
      "subscription_status": "active",
      "subscription_started_at": "2026-01-15T00:00:00.000Z"
    },
    "api_key": {
      "name": "Production API Key",
      "key_prefix": "bs_live_abc123...",
      "created_at": "2026-01-15T10:00:00.000Z",
      "last_used_at": "2026-02-27T18:30:00.000Z"
    },
    "rate_limits": {
      "per_minute": {
        "limit": 100,
        "used": 15,
        "remaining": 85
      },
      "per_day": {
        "limit": 10000,
        "used": 2340,
        "remaining": 7660
      }
    },
    "usage_last_30_days": [
      {
        "date": "2026-02-27",
        "requests": 380,
        "avg_response_time": 142
      }
    ]
  }
}

Error Codes

All errors follow this format:

{
  "error": {
    "message": "Human-readable error message",
    "code": "ERROR_CODE"
  }
}
HTTP Status Error Code Description
401 MISSING_API_KEY No API key provided in request
401 INVALID_API_KEY API key is invalid or revoked
403 SUBSCRIPTION_REQUIRED API access requires active subscription
404 NOT_FOUND Resource not found
429 RATE_LIMIT_MINUTE Exceeded 100 requests per minute
429 RATE_LIMIT_DAY Exceeded 10,000 requests per day
500 INTERNAL_ERROR Server error - contact support if persistent

Support

Need help or have questions?