The PolicySpan API.
Read-only access to the same evidence layer the product reads: bills, hearings and the spoken record, rulemaking, lobbying and campaign finance connected to policy, published fiscal evidence, and the research corpus of reports, tables and official statistics. Response bodies are identical to what the application reads, so a field you see in the product is the field you get here. Every record carries its source and date.
Base URL https://api.policyspan.ai/api/v1. 26 endpoints, generated from the live OpenAPI specification on 2026-11-02. The machine-readable spec is at /api/v1/openapi.json and the interactive reference at /api/v1/docs.
Authenticate
Keys belong to your organization, not to a person, and are scoped to the jurisdictions in your license. Send the key on every request, either way:
X-API-Key: ps_live_...
Authorization: Bearer ps_live_...
Start with /me. It returns the organization, the key's scopes, the licensed jurisdictions, the per-minute and per-month limits, and month-to-date usage. If this call works, everything else will.
curl -s https://api.policyspan.ai/api/v1/me -H "X-API-Key: $PS_KEY"
The key is shown once at issue time; we store only a hash. If a key leaks, ask for it to be revoked and a new one issued; revocation takes effect within a minute. Jurisdictions today: or (Oregon) and ca (California); GET /jurisdictions lists them with licensed true or false for your key. Keys are issued with a license; ask for one.
Limits and headers
Limits are guardrails on a flat-rate license, not a meter. Every response carries:
X-RateLimit-Limit requests allowed per minute
X-RateLimit-Remaining left in the current minute
X-Quota-Remaining left this month (absent when the key has no ceiling)
X-Request-Id quote this when reporting a problem
Bulk reads: GET /{jur}/bills returns the whole catalog in one call. Pull it once a day, then poll GET /{jur}/alerts for what moved. Do not crawl bill detail for every bill on a schedule; ask for an export if you need that.
Errors
Errors are JSON with a stable error code and a plain-language message.
| Status | error | Meaning |
|---|---|---|
| 401 | api_key_required | No key sent |
| 401 | api_key_invalid | Unknown, revoked, expired, or the organization is not active |
| 403 | jurisdiction_not_licensed | The key's scopes do not include this jurisdiction |
| 404 | not_found | Unknown jurisdiction or record |
| 429 | rate_limited | Over the per-minute limit; honor Retry-After |
| 429 | quota_exceeded | Over the monthly ceiling; contact us |
| 503 | service_unavailable | Mid-deploy or a migration pending; retry shortly |
Endpoints
{jur} is a jurisdiction code. Paths without it read across every state the key is licensed for.
Account
Who you are and what the key can read.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /jurisdictions | Jurisdictions this key can read | none |
GET /me | Who am I, what can I read, how much have I used | none |
Legislation
The bill record for a state: catalog, search, one bill with its history, versions, votes, money and filed positions, legislators, what moved.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /bills | Bill catalog across every licensed state (canonical policy record) | topicentitylimit default 200 |
GET /{jur}/alerts | What moved on the record in the last N days | days default 7topicentity |
GET /{jur}/bills | Bill catalog (filterable) | topic topic tag or keyword listentity an organization name to match in positions/lobbyingsession session id; default = currentlimit default 500 |
GET /{jur}/bills/search | Search bills by number or words | qlimit default 40 |
GET /{jur}/legislators | Legislator directory from the official record | session |
GET /{jur}/sessions | Session windows and today's status | none |
GET /{jur}/bills/{prefix}/{number} | One bill: record, history, money, positions | session |
Hearings and the spoken record
Posted meetings, every recorded meeting a bill came up in, and full-text search over verbatim transcripts with timestamped video links.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /{jur}/meetings | Posted hearings and meetings in a window around today | topicbodies comma list of body codeswindow_days default 180include_past_days default 240limit default 120 |
GET /{jur}/spoken-record/search | Full-text search over hearing transcripts | qsessionbodieslimit default 40 |
GET /{jur}/bills/{prefix}/{number}/spoken-record | Every recorded meeting where this bill came up, with verbatim transcript segments | session session id |
Pre-bill signals
What is forming before a bill exists: the spoken record, drafts and money, by topic.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /{jur}/signals | Pre-bill signals from the spoken record, bills and money | topicwindow_days default 90 |
Rulemaking
Notices from the official register and their explicit bill citations.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /{jur}/regulations | Rulemaking notices from the official register | qsectionagencyopen_only default sincelimit default 100 |
GET /{jur}/regulations/{znum} | One notice with its explicit bill citations | none |
Fiscal and economic evidence
The Legislature's published fiscal statements for a bill and official indicators for the state or a county.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /{jur}/economics/counties | Counties with indicator coverage | none |
GET /{jur}/economics/snapshot | Official indicators for the state or one county | fips default 06 |
GET /{jur}/bills/{prefix}/{number}/fiscal | Published fiscal evidence for a bill | none |
Research and official statistics
Published research and audit reports as full text with their tables, the scholarly literature by catalog, and official statistical series down to the county and the city, each with its license and exact source.
| Endpoint | Returns | Query parameters |
|---|---|---|
GET /research/metrics | Latest value of every series for a geography, with the U.S. comparison | geo default UStopic |
GET /research/publishers | Publishers in the research corpus, with what each is | none |
GET /research/search | Search research documents (bm25 over abstracts and full text) | qtopicpublishersincelimit default 10 |
GET /research/series | Official statistical series available (by topic) | topic |
GET /research/documents/{doc_id} | One document: matching sections (with pages) and its transcribed tables | qsections default 6tables default 12rows default 60 |
GET /research/documents/{doc_id}/tables | Every table transcribed from a document (verbatim cells, units, notes, page, PDF link, verified flag) | rows default 200 |
GET /research/series/{series_id} | Observations of one series for a geography | geo 'US', a state name or FIPS, or a county · default US |
GET /{jur}/bills/{prefix}/{number}/research | Research and official metrics tied to a bill: documented references first, then topical matches | session |
Examples
# What moved on the Oregon record this week
curl -s "$BASE/or/alerts?days=7" -H "X-API-Key: $PS_KEY"
# One California bill with its history, votes, money and filed positions
curl -s "$BASE/ca/bills/AB/1414" -H "X-API-Key: $PS_KEY"
# Research tied to a bill: documented references first, then topical matches and the state's metrics
curl -s "$BASE/or/bills/HB/2658/research" -H "X-API-Key: $PS_KEY"
# Every official series for a county, with the sites behind the water figures one call away
curl -s "$BASE/research/metrics?geo=Fresno%20County,%20California" -H "X-API-Key: $PS_KEY"
curl -s "$BASE/research/series/ca_dwr_gw_depth_to_water?geo=Fresno%20County,%20California" -H "X-API-Key: $PS_KEY"
# A GAO table, cell for cell, with the page it came from
curl -s "$BASE/research/documents/gao:GAO-27-108496/tables" -H "X-API-Key: $PS_KEY"
Reading the records
- Positions are filed labels. The record says an organization filed support or is on record opposing. It never says why.
- Lobbying rows are disclosed filings. They are not evidence of influence, and no spend figure is attached to a single bill unless the filing attaches it.
- Transcripts are verbatim machine output. Speaker labels are diarization numbers, not names. Confirm wording against the linked video before quoting formally.
- Research is documented or topical. A document is attached to a bill as documented only when the document names the bill (a CBO cost estimate, an LAO analysis). Everything else is a topical match on the bill's subject, labeled as such.
- Tables are the publisher's cells. Each carries its caption, units and Source line, a link that opens the PDF at that page, and a verified flag that means every number in the grid was found in the page text. Quote figures from verified tables only. Nothing is computed, rounded or converted.
- Series state their method. Every value carries the exact source call it came from; shares carry their denominator as universe. ACS and CHAS figures are survey estimates without margins of error.
- Water series are network roll-ups. A county figure is the median across the wells or gages a network monitors; universe is their count, and the series endpoint lists the sites behind the latest value. Where a state and the federal network both cover a county, both are returned and named.
- Housing production is by place. Permit rows are permits authorized, not units built; RHNA rows are one per planning cycle; the unincorporated part of a county is its own row. Place ids are the 7-digit state plus FIPS place code.
MCP
The same records are available as tools for Claude, ChatGPT and other MCP hosts, remote at https://mcp.policyspan.ai/mcp with your key as Authorization: Bearer ps_live_.... The tools carry the same names as the endpoint groups above and the same reading rules.
What each source is and how to read it is on the Data & Sourcing pages, including Research & statistics. Questions, a key, or an export? Reach out at rj@policyspan.ai.