Developer Guide

Using the API

Use this guide for the rules that stay consistent across the API: authentication, pagination, includes, response structure, and rate limits. Route-by-route paths live in Reference, and copy-ready request patterns live in Recipes.

Quickstart

Go from zero to a live request in three steps. Start with a verified account, send header-authenticated requests, and follow next_url values instead of rebuilding pagination yourself.

1

Create your account

Every new account starts on Free. After email verification, your first API key is ready immediately and you can upgrade to Pro later in the dashboard.

2

Send your first request

Use X-API-Key or Authorization: Bearer .... The browser address bar by itself will not send your key.

3

Expand only when needed

Use include= on detail endpoints to fetch related data in one call. Keep list endpoints lean until you know you need more.

Authentication

Every JSON endpoint under /api/v1 expects your key in X-API-Key or an Authorization: Bearer ... header.

Header-based auth only
Use curl, Postman, Insomnia, browser dev tools, or your application code. The address bar is not enough because it cannot send the request header.
curl -H "X-API-Key: YOUR_KEY" \
  "https://legilist.com/api/v1/bills?congress=119&per_page=5"

Pagination

Collection routes return pagination metadata. If you ask for more than the maximum page size, the API uses the highest allowed value and reflects that in the response links.

  • Default collection size depends on the endpoint.
  • per_page is capped at 100.
  • next_url and prev_url preserve your active filters.
  • Page 1 stays clean and does not force page=1 into the URL.
{
  "meta": {
    "page": 1,
    "per_page": 100,
    "total": 5763,
    "total_pages": 58,
    "prev_page": null,
    "next_page": 2,
    "prev_url": null,
    "next_url": "https://legilist.com/api/v1/topics?per_page=100&page=2"
  }
}

Include semantics

Detail endpoints use include= for related data. If you request an unsupported include, the API ignores it and reports that in meta.ignored_includes.

Keep list calls lean
Use includes on detail routes when you want one stitched response. Bill includes such as actions, texts, and amendments can add a lot of data.
  • Bills: actions, subjects, summaries, texts, titles, cosponsors, committees, related, amendments, laws, votes
  • Legislators: biography, terms, committee_memberships
  • Votes: results
  • Committees: memberships
  • Field naming: include tokens usually match the response key. Bill detail uses include=related and returns data.related_bills.
curl -H "X-API-Key: YOUR_KEY" \
  "https://legilist.com/api/v1/bills/119/HR/1?include=actions,texts,amendments,related,laws,votes,notreal"

Response conventions

Responses follow the same small set of patterns across the API, so clients can move between resources without special-case parsing.

Collection routes
Collection endpoints return data as an array and pagination in top-level meta.
Detail routes
Detail endpoints return one record in data. Related data appears only when you request it with include=.
Topic detail
Topic detail keeps the topic record and its bill list in data, with bill pagination links in the same top-level meta block used elsewhere in the API.
URLs
site_url points to the public LegiList page when one exists. api_url points back to the canonical API endpoint.
Nulls and sparse data
Blank strings and zero-style dates are cleaned up where practical. Optional fields may still be null when the source data is limited.
Identity
Bills are identified by congress, type, and number; laws by congress, law_type, and law_number; legislators by bioguide_id.
Current-Congress committee activity
Committee meetings and nominations are current-Congress-only subresources. Their responses expose that scope explicitly.

Errors and limits

Error responses are predictable, and rate-limit headers tell your app when to pause and retry.

Supported values matter
If you use an unsupported filter or path value, the API returns 400 invalid_parameter. Accepted values are listed in Reference.
Status Code Meaning
400 invalid_parameter A filter or path value used an unsupported option.
401 missing_api_key The request did not include X-API-Key or a bearer token header.
401 invalid_api_key The supplied key hash did not match an active API key.
404 not_found The requested route or record does not exist.
429 rate_limit_exceeded The request exceeded a per-second or expensive-route limit.
429 daily_quota_exceeded The account exceeded its daily request quota.
503 schema_not_ready The API has not been fully set up yet.
{
  "error": {
    "code": "invalid_parameter",
    "message": "Invalid value for chamber.",
    "parameter": "chamber"
  }
}

Rate-limit headers

Every authenticated response includes daily and per-second headers so your app can back off before it hits a hard limit.

  • X-RateLimit-Limit-Day
  • X-RateLimit-Remaining-Day
  • X-RateLimit-Reset-Day
  • X-RateLimit-Limit-Second
  • X-RateLimit-Remaining-Second
  • X-RateLimit-Reset-Second
  • Free: 1,000/day, 5/sec per key
  • Pro: 25,000/day, 10/sec per key
{
  "data": [...],
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 178847,
    "total_pages": 8943,
    "prev_page": null,
    "next_page": 2,
    "prev_url": null,
    "next_url": "https://legilist.com/api/v1/bills?per_page=20&page=2"
  }
}

Next step

When you know how requests work, move to Reference for exact routes and parameters, or jump to Recipes for common workflows.