Developer access
REST API documentation
Bill Commons offers free public read endpoints and a separate alert signup endpoint. The API serves JSON over HTTPS with a consistent pagination envelope, ETags, and request IDs. Interactive OpenAPI 3.1 docs are available at https://api.billcommons.org/docs.
Base URL
https://api.billcommons.orgTry a real API result
Search North Carolina for HB 920, then load the bill record using the ID returned by search. These public read requests need no API key.
The result will appear here when you run the example.
Authentication & rate limits
No API key is required for public reads. Anonymous minute and daily limits vary by route: bill and search requests can have a tighter burst limit than lighter lookups. Check each response's X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers, and honor Retry-After on a 429. A free Developer key raises the daily allowance, and paid tiers support higher-volume use; see API keys and bulk access for the current limits.
Pagination envelope
Every list endpoint returns the same shape. The values below illustrate the structure; source_freshness can be null and never proves official freshness:
{
"data": [ ... ],
"pagination": {
"page": 1,
"per_page": 20,
"total": 431,
"total_pages": 22
},
"meta": {
"source_freshness": null,
"api_version": "v1",
"request_id": "a1b2c3d4"
}
}Endpoints
| Method | Path | Description |
|---|---|---|
| GET | /api/v1/jurisdictions | List all 51 jurisdictions. |
| GET | /api/v1/jurisdictions/{id} | Get one jurisdiction. |
| GET | /api/v1/sessions | List legislative sessions (filter by jurisdiction, active). |
| GET | /api/v1/bills | List bills. Filters: jurisdiction, session, identifier, chamber, status, subject, sponsor. (No committee or date-range filter — those were listed here before they existed.) |
| GET | /api/v1/bills/{id} | Get a bill with full detail (sponsors, actions, versions, votes, sources). |
| GET | /api/v1/bills/{id}/versions | List a bill's text versions. |
| GET | /api/v1/bills/{id}/actions | List a bill's full action history. |
| GET | /api/v1/bills/{id}/sponsors | List a bill's sponsors and cosponsors. |
| GET | /api/v1/bills/{id}/votes | List recorded votes, including member-level detail. |
| GET | /api/v1/bills/{id}/documents | List associated documents (fiscal notes, amendments, etc). |
| GET | /api/v1/feeds/{jurisdiction}.atom?kind=actions&bill_id={id} | Follow one bill's recorded action updates in an Atom reader. Entries cover the last 30 days and may lag the legislature. |
| GET | /api/v1/people | NOT COLLECTED — always returns []. Legislator records are not ingested; responses carry data_status: "not_collected". Sponsor names are available per bill. |
| GET | /api/v1/people/{id} | NOT COLLECTED — always 404s. No legislator records exist. |
| GET | /api/v1/committees | NOT COLLECTED — always returns []. Committee referrals are visible in each bill's action history. |
| GET | /api/v1/committees/{id} | NOT COLLECTED — always 404s. |
| GET | /api/v1/events | NOT COLLECTED — always returns []. No hearing or calendar data is ingested for any jurisdiction. Empty means we lack the data, not that nothing is scheduled. |
| POST | /api/v1/alerts/subscribe | Temporarily unavailable while email confirmation and delivery are verified. Existing unsubscribe links continue to work. |
| GET | /api/v1/search | Full-text and structured search across all jurisdictions. |
| GET | /api/v1/sources | List source registry entries per jurisdiction. |
| GET | /api/v1/coverage | Public per-jurisdiction coverage matrix. |
| GET | /api/v1/health | Liveness check (DB ping). |
| GET | /api/v1/ready | Readiness check. |
Example: search for a bill
curl "https://api.billcommons.org/api/v1/search?q=HB+920&jurisdiction=NC"import requests
resp = requests.get(
"https://api.billcommons.org/api/v1/search",
params={"q": "HB 920", "jurisdiction": "NC"},
)
resp.raise_for_status()
data = resp.json()
for bill in data["data"]:
print(bill["identifier"], bill["title"])const url = new URL("https://api.billcommons.org/api/v1/search");
url.searchParams.set("q", "HB 920");
url.searchParams.set("jurisdiction", "NC");
const res = await fetch(url);
const { data } = await res.json();
for (const bill of data) {
console.log(bill.identifier, bill.title);
}Example: get a bill's full record
The search above currently finds North Carolina HB 920. Copy itsid field, not its bill number, into the detail URL. Here is a complete request using that record:
curl -fsS "https://api.billcommons.org/api/v1/bills/0da038a9-e049-42cc-b16e-2054f94e21d3"The response includes the bill's latest action, source URL, and retrieved_at timestamp. That timestamp records our local retrieval, not the official source's freshness. Check the jurisdiction's coverage and data health before treating an empty or old result as a current legislative fact.
All bill and document text is sourced from official legislative records or Open States and is provided as-is; see methodology for attribution and known limitations.