LegisDataLegisData

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.

GET

Search bills

/v1/bill-search/{state}

Search a state's bills, newest session first. Combine any of the filters below.

Endpoint
https://legisdata.dev/v1/bill-search/TX?status=passed&topic=healthcare

Parameters

(*) Required
ParameterTypeExample
state *stringTX
pagenumber1
page-sizenumber25
session-yearnumber2025
statusstringpassed
topicstringhealthcare
chamber-typestringupper
is-resolutionstringy
bill-name-likestringbudget
keyword-likestringeducation
sponsor-name-likestringHughes

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

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.

Endpoint
https://legisdata.dev/v1/bill-detail/TX/2025/HB%2011

Parameters

(*) Required
ParameterTypeExample
state *stringTX
year *number2025
number *stringHB 11
include-bill-textstring1

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…"
      }
    ]
  }
}
GET

Search legislators

/v1/legislator-search/{state}

Search a state's legislators by chamber, party, district, or name.

Endpoint
https://legisdata.dev/v1/legislator-search/TX?chamber-type=upper&party=R

Parameters

(*) Required
ParameterTypeExample
state *stringTX
pagenumber1
page-sizenumber25
name-likestringHughes
chamber-typestringupper
partystringR
districtstring1

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

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).

Endpoint
https://legisdata.dev/v1/legislator-detail/cmqtt3pgl0000sf3sq1u07aez

Parameters

(*) Required
ParameterTypeExample
id *stringcmqtt3pgl0000sf3sq1u07aez

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
  }
}
GET

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.

Endpoint
https://legisdata.dev/v1/legislator-vote-history/cmqtt3pgl0000sf3sq1u07aez?vote=yes

Parameters

(*) Required
ParameterTypeExample
id *stringcmqtt3pgl0000sf3sq1u07aez
pagenumber1
page-sizenumber25
votestringyes
session-yearnumber2025
statusstringpassed
topicstringcrime
chamber-typestringupper
is-resolutionstringy
bill-name-likestringelection
keyword-likestringvoting
sponsor-name-likestringKing

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_bills

Search a state's bills by topic, status, chamber, sponsor.

get_bill

Full detail: summary, sponsors, scores, floor votes, roll call.

search_legislators

Find legislators by chamber, party, district, name.

get_legislator

Profile + vote-derived economic/social scores.

get_legislator_votes

A legislator's yes/no floor votes, joined to bills.

compare_legislators

Ideology-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.

50
States
346,751
Bills
8,992,425
Recorded votes
7,960
Legislators

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 20222026. 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_call can 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 return null.
  • Historical depth is uneven across states, reflecting differences in source availability.

Pricing

$150/month

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 key

Already subscribed? Sign in to manage your keys. Questions? [email protected].