API documentation
Read-only access to aggregated U.S. state legislative data, available two ways: a REST API and an MCP server for AI agents. Same data, same shapes. REST base URL https://legisdata.dev/v1; full machine-readable spec at /v1/openapi.json.
Overview
Authentication
Every request needs an API key, sent as a bearer token. Keys look like vd_live_… and are shown once at creation.
curl -H "Authorization: Bearer vd_live_…" "https://legisdata.dev/v1/bill-search/TX?status=passed"
Chambers
Chambers are normalized across states to upper (senate) and lower (house / assembly). Every bill and legislator carries both the raw source label (chamber) and the normalized chamber_type; filter with ?chamber-type=upper|lower. The same normalization applies to status (e.g. pending_upper_vote).
Pagination
List endpoints are page-based. Pass ?page= (1-based) and follow pagination.next_url — an absolute URL — to the next page. When next_url is null, you have reached the last page. Page size defaults to your plan’s maximum (100); request a smaller page with ?page-size= (values above 100 are clamped) to keep responses light — handy for MCP or bandwidth-constrained clients.
{
"pagination": {
"page": 1, "page_size": 100, "returned_count": 100,
"total_count": 2222, "total_pages": 23,
"next_url": "https://legisdata.dev/v1/bill-search/TX?page=2", "prev_url": null
},
"data": [ /* records */ ]
}Rate limits & quota
The Standard plan allows 120 requests / minute and 500,000 requests / calendar month, with a max page size of 100. Every response carries X-RateLimit-* (per-minute) and X-Quota-* (per-month) headers so you can track usage. Exceeding the rate limit or the monthly quota returns 429 with an error body; rate-limit responses also include Retry-After.
Errors
Errors use a consistent envelope and standard status codes:
{ "error": { "code": "unauthorized", "message": "Invalid API key." } }REST Endpoints
{state} is a two-letter USPS code (e.g. TX). Topics use short labels: taxes, budget, affordability, crime, immigration, ai, climate, housing, healthcare, agriculture, mining, traffic, wages, other. Hit Try it live on any endpoint to run it against real data.
Search bills
/v1/bill-search/{state}Search a state's bills, newest session first. Combine any of the filters below.
https://legisdata.dev/v1/bill-search/TX?status=passed&topic=healthcareParameters
(*) Required| Parameter | Type | Example |
|---|---|---|
| state * | string | TX |
| page | number | 1 |
| page-size | number | 25 |
| session-year | number | 2025 |
| status | string | passed |
| topic | string | healthcare |
| chamber-type | string | upper |
| is-resolution | string | y |
| bill-name-like | string | budget |
| keyword-like | string | education |
| sponsor-name-like | string | Hughes |
Response
{
"pagination": {
"page": 1,
"page_size": 100,
"returned_count": 100,
"total_count": 2222,
"total_pages": 23,
"next_url": "https://legisdata.dev/v1/bill-search/TX?page=2",
"prev_url": null
},
"data": [
{
"session_year": 2025,
"bill_number": "SB 2972",
"bill_name": "Relating to expressive activities at public institutions of higher education.",
"key_words": "Education--Higher; Civil Remedies & Liabilities",
"topics": ["other"],
"chamber": "Senate",
"chamber_type": "upper",
"status": "passed",
"latest_stage": "executive_signature",
"is_resolution": false,
"summary": "S.B. 2972 guarantees the rights of students and university employees to engage in expressive activities …",
"bill_sponsors": [
{
"name": "Brandon Creighton",
"legislator_id": "cmqtt3s1a000psf3s…",
"legislator_url": "https://legisdata.dev/v1/legislator-detail/cmqtt3s1a000psf3s…"
}
],
"detail_url": "https://legisdata.dev/v1/bill-detail/TX/2025/SB%202972"
}
]
}Get a bill
/v1/bill-detail/{state}/{year}/{number}Full detail for one bill: summary, sponsors, derived scores, per-chamber floor history, and the most-recent roll call. Pass include-bill-text=1 to also return the full legislative text (omitted by default — it can be multi-megabyte). URL-encode spaces in the bill number.
https://legisdata.dev/v1/bill-detail/TX/2025/HB%2011Parameters
(*) Required| Parameter | Type | Example |
|---|---|---|
| state * | string | TX |
| year * | number | 2025 |
| number * | string | HB 11 |
| include-bill-text | string | 1 |
Response
{
"data": {
"session_year": 2025,
"bill_number": "HB 11",
"bill_name": "Relating to licensing reciprocity agreements …",
"topics": ["other"],
"chamber": "House",
"chamber_type": "lower",
"status": "passed",
"latest_stage": "executive_signature",
"is_resolution": false,
"summary": "H.B. 11 directs the Texas Department of Licensing and Regulation …",
"bill_text": "AN ACT relating to licensing … SECTION 1. … (only present when include-bill-text=1)",
"bipartisan_index": 100,
"popularity_index": 100,
"economic_score": 4.2,
"social_score": 3.0,
"velocity": 1.1,
"bill_sponsors": [
{
"name": "Dade Phelan",
"chamber": "House",
"chamber_type": "lower",
"party": "R",
"legislator_id": "cmqveg29m0086sffx…",
"legislator_url": "https://legisdata.dev/v1/legislator-detail/cmqveg29m0086sffx…"
}
],
"floor_vote_history": [
{
"chamber": "House",
"chamber_type": "lower",
"timestamp": "2025-04-24T07:00:00.000Z",
"most_recent": true,
"result": "pass"
}
],
"last_roll_call": [
{
"name": "Paul Bettencourt",
"party": "R",
"chamber_type": "upper",
"vote": "yes",
"legislator_id": "cmqtt3rq8000isf3s…",
"legislator_url": "https://legisdata.dev/v1/legislator-detail/cmqtt3rq8000isf3s…"
}
]
}
}Search legislators
/v1/legislator-search/{state}Search a state's legislators by chamber, party, district, or name.
https://legisdata.dev/v1/legislator-search/TX?chamber-type=upper&party=RParameters
(*) Required| Parameter | Type | Example |
|---|---|---|
| state * | string | TX |
| page | number | 1 |
| page-size | number | 25 |
| name-like | string | Hughes |
| chamber-type | string | upper |
| party | string | R |
| district | string | 1 |
Response
{
"pagination": {
"page": 1,
"page_size": 100,
"returned_count": 18,
"total_count": 18,
"total_pages": 1,
"next_url": null,
"prev_url": null
},
"data": [
{
"name": "Bryan Hughes",
"chamber": "Senate",
"chamber_type": "upper",
"party": "R",
"district": "1",
"legislator_id": "cmqtt3pgl0000sf3sq1u07aez",
"legislator_url": "https://legisdata.dev/v1/legislator-detail/cmqtt3pgl0000sf3sq1u07aez"
}
]
}Get a legislator
/v1/legislator-detail/{id}A legislator's profile. economic_score and social_score are computed on request from their recorded floor votes (1 conservative … 5 liberal).
https://legisdata.dev/v1/legislator-detail/cmqtt3pgl0000sf3sq1u07aezParameters
(*) Required| Parameter | Type | Example |
|---|---|---|
| id * | string | cmqtt3pgl0000sf3sq1u07aez |
Response
{
"data": {
"legislator_id": "cmqtt3pgl0000sf3sq1u07aez",
"name": "Bryan Hughes",
"chamber": "Senate",
"chamber_type": "upper",
"party": "R",
"district": "1",
"website": "https://senate.texas.gov/member.php?d=1",
"bio": null,
"photo_url": null,
"economic_score": 2.8,
"social_score": 2.8
}
}Legislator vote history
/v1/legislator-vote-history/{id}Every yes/no floor vote the legislator cast, newest first, joined to its bill. The legislator's identity is returned once at the top level.
https://legisdata.dev/v1/legislator-vote-history/cmqtt3pgl0000sf3sq1u07aez?vote=yesParameters
(*) Required| Parameter | Type | Example |
|---|---|---|
| id * | string | cmqtt3pgl0000sf3sq1u07aez |
| page | number | 1 |
| page-size | number | 25 |
| vote | string | yes |
| session-year | number | 2025 |
| status | string | passed |
| topic | string | crime |
| chamber-type | string | upper |
| is-resolution | string | y |
| bill-name-like | string | election |
| keyword-like | string | voting |
| sponsor-name-like | string | King |
Response
{
"pagination": {
"page": 1,
"page_size": 100,
"returned_count": 100,
"total_count": 474,
"total_pages": 5,
"next_url": "https://legisdata.dev/v1/legislator-vote-history/cmqtt3pgl0000sf3sq1u07aez?page=2",
"prev_url": null
},
"legislator": {
"legislator_id": "cmqtt3pgl0000sf3sq1u07aez",
"name": "Bryan Hughes",
"legislator_url": "https://legisdata.dev/v1/legislator-detail/cmqtt3pgl0000sf3sq1u07aez"
},
"data": [
{
"session_year": 2025,
"bill_number": "SB 2972",
"bill_name": "Relating to expressive activities at public institutions of higher education.",
"vote": "yes",
"vote_date": "2025-06-01",
"topics": ["other"],
"status": "passed",
"is_resolution": false,
"summary": "S.B. 2972 guarantees the rights of students …",
"detail_url": "https://legisdata.dev/v1/bill-detail/TX/2025/SB%202972"
}
]
}MCP server
The same dataset is exposed as a Model Context Protocol server, so assistants like Claude can query legislation as native tools — with enum-constrained inputs and token-frugal, model-shaped responses. It authenticates with the same vd_live_… key.
search_billsSearch a state's bills by topic, status, chamber, sponsor.
get_billFull detail: summary, sponsors, scores, floor votes, roll call.
search_legislatorsFind legislators by chamber, party, district, name.
get_legislatorProfile + vote-derived economic/social scores.
get_legislator_votesA legislator's yes/no floor votes, joined to bills.
compare_legislatorsIdeology-score table for several legislators at once.
It also serves discovery resources (legisdata://meta/topics, states, vocab) and workflow prompts (analyze_bill, legislator_profile). Point a stdio MCP client at it:
{
"mcpServers": {
"legisdata": {
"command": "node",
"args": ["/path/to/legisdata-mcp/dist/index.js"],
"env": {
"LEGISDATA_API_KEY": "vd_live_…",
"LEGISDATA_BASE_URL": "https://legisdata.dev"
}
}
}
}A hosted Streamable-HTTP endpoint is also available for remote MCP clients.
Dataset
LegisData aggregates public records from official state sources across all 50 states — bills, roll-call votes, legislators, and lifecycle events — then normalizes and enriches them with derived metrics.
What's included
- Bills — number, title, session year, sponsors, status & lifecycle stage, a plain-language summary, the full legislative text (via bill-detail), and topic labels.
- Votes — floor-vote outcomes and, where the source publishes them, per-member roll calls.
- Legislators — chamber, party, district, and vote-derived ideology scores.
- Derived metrics — bipartisan index, popularity index, economic & social scores, and legislative velocity.
Coverage & history
All 50 states are covered, with sessions currently spanning 2022–2026. Historical depth varies by state and by what each state publishes — most cover the current and prior session, and several go back further. Data is refreshed on a rolling schedule (not real-time), so expect some lag behind the official source.
Known limitations
- Roll calls vary. Some states publish only aggregate floor outcomes, not per-member votes — so
last_roll_callcan be empty even when a bill passed. - Derived scores are directional. Topic labels and economic/social scores are model-derived from bill text; treat them as signal, not official classification.
- Bipartisan index needs parties. Nonpartisan chambers (e.g. Nebraska) omit it.
- Legislator scores need votes.
economic_score/social_scoreare computed from a member's scored floor votes; members without qualifying votes returnnull. - Historical depth is uneven across states, reflecting differences in source availability.
Pricing
Flat rate, one plan. Full access to every REST endpoint and the MCP server across all 50 states, with 500,000 requests / month and 120 requests / minute.
Get your API keyAlready subscribed? Sign in to manage your keys. Questions? [email protected].