Bills

Sixteen endpoints: one search surface over every bill in the corpus, one record fetch, and fourteen sub-resources that hang off a bill_id — sponsors, roll calls, action history, text versions, amendments, subjects, calendar events, statute citations, staff analyses, cross-references, referrals, supplements, and computed text diffs.

Every path is relative to https://delilah-api.jsv21b.workers.dev and requires an X-API-Key header (Authentication). Single records return { data: {…} }, collections return { data: [ … ] }. In the JSON samples below the field names are exactly what the API returns; values written as <type> are placeholders.

One thing to get right before you filter on it: status_idfollows this API’s own ladder, where 5 is Signed into Law— not another provider’s. The full ladder is on the API Reference overview.

List bills

GET/v1/bills

Search and filter bills across all 52 jurisdictions. Results are ordered newest-updated first and carry a pagination object.

ParameterTypeRequiredDescription
statestringOptional2-letter postal code (e.g. FL), DC, or US for Congress.
session_idintegerOptionalNarrow to one legislative session.
bill_numberstringOptionalMatch a bill number. Accepts compact (HB1) or padded (HB0001) form — both normalize to the same row.
qstringOptionalFree-text search across title, description, and subject names.
topicstringOptionalCanonical topic slug, e.g. healthcare. See Topics.
subjectstringOptionalRaw subject name (ILIKE match).
sponsor_last_namestringOptionalBills sponsored by anyone with this surname.
status_idintegerOptionalThis API’s status scheme (5 = Signed, 8 = Chaptered), not LegiScan’s.
title_containsstringOptionalSubstring match on the title.
updated_sincestring (date-time)OptionalISO-8601 date or timestamp. Non-ISO values return 400.
limitintegerOptionalMax rows. Defaults to 50, clamped to 500.
offsetintegerOptionalRow offset. Defaults to 0.
bash
curl "https://delilah-api.jsv21b.workers.dev/v1/bills?state=FL&topic=healthcare&limit=1" \
  -H "X-API-Key: dk_live_…"
json
{
  "data": [
    {
      "bill_id": "<int>",
      "state_id": "<int>",
      "state_abbr": "<string>",
      "session_id": "<int>",
      "bill_number": "<string>",
      "bill_type_id": "<int>",
      "bill_type_name": "<string>",
      "body_id": "<int>",
      "current_body_id": "<int>",
      "status_id": "<int>",
      "status_date": "<date>",
      "title": "<string>",
      "description": "<string>",
      "state_url": "<string>",
      "updated": "<timestamp>",
      "created": "<timestamp>",
      "change_hash": "<string>",
      "content_hash": "<string>",
      "summary": "<string|null>",
      "last_action": "<string|null>",
      "completed": "<int|null>",
      "pending_committee_id": "<int|null>"
    }
  ],
  "pagination": { "limit": 1, "offset": 0, "returned": 1 }
}

last_actionis the shortcut worth knowing: it carries the latest action text, so a “what happened most recently” view does not need a second call to /history. completed is a terminal-state flag, which is safer to read than inferring finality from status_id.

Get one bill

GET/v1/bills/{bill_id}

The same record as a list row, fetched by id. Returns 404 not_found when no bill carries that id.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
bash
curl "https://delilah-api.jsv21b.workers.dev/v1/bills/1234567" \
  -H "X-API-Key: dk_live_…"
json
{
  "data": {
    "bill_id": "<int>",
    "state_abbr": "<string>",
    "session_id": "<int>",
    "bill_number": "<string>",
    "status_id": "<int>",
    "status_date": "<date>",
    "title": "<string>",
    "description": "<string>",
    "last_action": "<string|null>",
    "state_url": "<string>",
    "updated": "<timestamp>"
  }
}

Bill votes

GET/v1/bills/{bill_id}/votes

Every roll call taken on the bill, newest first, with header tallies. Pass a roll_call_id from here to /v1/votes to get how each member voted.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
bash
curl "https://delilah-api.jsv21b.workers.dev/v1/bills/1234567/votes" \
  -H "X-API-Key: dk_live_…"
json
{
  "data": [
    {
      "roll_call_id": "<int>",
      "bill_id": "<int>",
      "roll_call_body_id": "<int>",
      "body": "<string>",
      "vote_date": "<date>",
      "description": "<string>",
      "yea": "<int>",
      "nay": "<int>",
      "nv": "<int>",
      "absent": "<int>",
      "total": "<int>",
      "passed": "<int>",
      "state_url": "<string>"
    }
  ]
}

Bill sponsors

GET/v1/bills/{bill_id}/sponsors

Sponsors and cosponsors in sponsor_order. sponsor_type_id is 1 for a primary sponsor and 2 for a cosponsor; sponsor_type_name spells it out.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "people_id": "<int>",
      "name": "<string>",
      "first_name": "<string>",
      "last_name": "<string>",
      "party_id": "<int>",
      "party_name": "<string>",
      "district": "<string>",
      "sponsor_order": "<int>",
      "sponsor_type_id": "<int>",
      "sponsor_type_name": "<string>"
    }
  ]
}

Bill action history

GET/v1/bills/{bill_id}/history

The chamber-by-chamber action trail in history_step order. history_major flags the steps that moved the bill rather than the procedural noise around them.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "history_step": "<int>",
      "history_date": "<date>",
      "history_action": "<string>",
      "history_body_id": "<int>",
      "body_name": "<string>",
      "history_major": "<int>"
    }
  ]
}

Bill text versions

GET/v1/bills/{bill_id}/texts

Each published version of the bill’s text — introduced, committee substitute, engrossed, enrolled — newest first. state_urlpoints at the document on the legislature’s own site; the text_id values are what you feed to /diff.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "text_id": "<int>",
      "bill_id": "<int>",
      "bill_text_type_id": "<int>",
      "text_type": "<string>",
      "text_date": "<date>",
      "size_bytes": "<int>",
      "word_count": "<int>",
      "state_url": "<string>"
    }
  ]
}

Bill amendments

GET/v1/bills/{bill_id}/amendments

Filed amendments, newest first. adopted records whether the chamber took it up successfully.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "amendment_id": "<int>",
      "bill_id": "<int>",
      "adopted": "<int>",
      "amendment_body_id": "<int>",
      "body": "<string>",
      "amendment_date": "<date>",
      "amendment_title": "<string>",
      "amendment_desc": "<string>",
      "amendment_mime_id": "<int>",
      "amendment_size": "<int>",
      "state_url": "<string>"
    }
  ]
}

Bill subjects

GET/v1/bills/{bill_id}/subjects

The raw subject tags the legislature applied to this bill. These are the state’s own vocabulary; the canonical cross-state taxonomy that folds them into ~40 buckets lives at /v1/topics.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "subject_id": "<int>",
      "subject_name": "<string>"
    }
  ]
}

Bill calendar

GET/v1/bills/{bill_id}/calendar

Scheduled events for the bill — hearings, floor votes, markups — newest first. event_type_name is the readable form of event_type_id.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "event_hash": "<string>",
      "event_type_id": "<int>",
      "event_type_name": "<string>",
      "event_date": "<date>",
      "event_time": "<string>",
      "event_location": "<string>",
      "event_desc": "<string>"
    }
  ]
}

Statute citations

GET/v1/bills/{bill_id}/citations

The sections of existing statute a bill amends or creates, for the states that publish them. States that do not return an empty data array rather than an error.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "id": "<int>",
      "bill_id": "<int>",
      "citation_type": "<string>",
      "citation_number": "<string>",
      "catchline": "<string>",
      "bill_page": "<string>",
      "state_url": "<string>",
      "created": "<timestamp>"
    }
  ]
}

Staff analyses

GET/v1/bills/{bill_id}/analyses

Committee and professional-staff analyses — the documents that explain what a bill actually does in the chamber’s own words. Populated for the deep states; empty elsewhere.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "id": "<int>",
      "bill_id": "<int>",
      "analysis_type": "<string>",
      "analysis_title": "<string>",
      "author": "<string>",
      "analysis_date": "<date>",
      "state_url": "<string>",
      "created": "<timestamp>"
    }
  ]
}

Same-as and similar-to cross-references

GET/v1/bills/{bill_id}/sast

Companion and related-bill links — the House twin of a Senate bill, a carryover from a prior session, a bill this one replaces. sast_type names the relationship, and sast_bill_id is fetchable directly.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "sast_type_id": "<int>",
      "sast_type": "<string>",
      "sast_bill_id": "<int>",
      "sast_bill_number": "<string>"
    }
  ]
}

Committee referrals

GET/v1/bills/{bill_id}/referrals

Which committees the bill was sent to and when, in referral order. committee_id keys straight into /v1/committees.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "bill_id": "<int>",
      "committee_id": "<int>",
      "committee_name": "<string>",
      "referral_date": "<date>",
      "referral_step": "<int>"
    }
  ]
}

Text change timeline

GET/v1/bills/{bill_id}/changes

Every computed diff between consecutive text versions of this bill, oldest first — the data behind an “introduced → substitute → engrossed → enrolled” timeline. Whitespace-only diffs are excluded unless you ask for them. The response adds a summary object alongside data.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
include_whitespacestringOptionalSet to 1 to include diffs that changed only whitespace.
bash
curl "https://delilah-api.jsv21b.workers.dev/v1/bills/1234567/changes" \
  -H "X-API-Key: dk_live_…"
json
{
  "data": [
    {
      "from_text_id": "<int>",
      "to_text_id": "<int>",
      "from_type_id": "<int>",
      "to_type_id": "<int>",
      "from_created": "<timestamp>",
      "to_created": "<timestamp>",
      "added_chars": "<int>",
      "removed_chars": "<int>",
      "added_lines": "<int>",
      "removed_lines": "<int>",
      "similarity": "<float>",
      "is_whitespace_only": "<bool>",
      "changed_sections": "<json>",
      "highlights": "<json>",
      "diff_truncated": "<bool>",
      "computed_at": "<timestamp>"
    }
  ],
  "summary": { "bill_id": "<int>", "count": "<int>" }
}

Unified diff between two versions

GET/v1/bills/{bill_id}/diff

The full unified diff between two specific text versions. Both from and to are required and take text_id values from /v1/bills/{bill_id}/texts.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
fromintegerRequiredThe earlier text_id.
tointegerRequiredThe later text_id.
bash
curl "https://delilah-api.jsv21b.workers.dev/v1/bills/1234567/diff?from=111&to=222" \
  -H "X-API-Key: dk_live_…"
json
{
  "data": {
    "bill_id": "<int>",
    "from_text_id": "<int>",
    "to_text_id": "<int>",
    "from_type_id": "<int>",
    "to_type_id": "<int>",
    "from_created": "<timestamp>",
    "to_created": "<timestamp>",
    "diff_unified": "<string>",
    "diff_truncated": "<bool>",
    "added_chars": "<int>",
    "removed_chars": "<int>",
    "added_lines": "<int>",
    "removed_lines": "<int>",
    "similarity": "<float>",
    "is_whitespace_only": "<bool>",
    "changed_sections": "<json>",
    "highlights": "<json>",
    "computed_at": "<timestamp>"
  }
}

Diffs are precomputed rather than generated on request. A pair that has not been processed yet returns 404 with the code diff_not_computed— that is a “not yet”, not a “never”, so it is worth retrying rather than treating as a permanent absence.

Supplements

GET/v1/bills/{bill_id}/supplements

Fiscal notes, analyses, and summaries attached to the bill, newest first. supplement_type names which kind, and state_url links the source document.

ParameterTypeRequiredDescription
bill_idinteger (path)RequiredThe bill identifier. Non-integer values return 400 bad_request.
json
{
  "data": [
    {
      "supplement_id": "<int>",
      "bill_id": "<int>",
      "supplement_type_id": "<int>",
      "supplement_type": "<string>",
      "supplement_date": "<date>",
      "title": "<string>",
      "description": "<string>",
      "state_url": "<string>",
      "supplement_mime_id": "<int>",
      "supplement_size": "<int>"
    }
  ]
}