API docs

Getting started with the API

The only source of AI-optimized endorsement and election data: every endorsement we collect, with the elections, contests and endorsers behind it, queried when you need it. Base URL https://api.ballotdata.ai. Everything is JSON over HTTPS. Machine-readable: /openapi.json (OpenAPI 3.1). To have new endorsements sent to you instead, see the Endorsement Stream docs (returning for 2028).

Your account and first key

  1. Buy API access for some states or every state at ballotdata.ai, and choose your API account’s password at checkout. There’s no separate sign-up here.
  2. Once you’ve paid, your account opens on its own and we email a link to confirm your address. Confirm it, then sign in with the password you chose.
  3. Create a key in the console. You see it only once.
  4. Send it on every request, with plain HTTP or our client libraries for JavaScript and Python (npm install ballotdata, pip install ballotdata):
GET /v1/endorsements
curl "https://api.ballotdata.ai/v1/endorsements?elections=ca-2026-11-03-general&categories=labor" \
  -H "Authorization: Bearer $BALLOTDATA_API_KEY"
Response200
{
  "data": [
    {
      "id": 90211,
      "rank": 1,
      "published_on": "2026-09-18",
      "added_by": "data_load",
      "endorser": {
        "id": 512,
        "slug": "sf-labor-council",
        "name": "San Francisco Labor Council"
      },
      "contest": {
        "id": 4410,
        "title": "Member, Board of Supervisors, District 8"
      },
      "election": {
        "id": 3,
        "slug": "ca-2026-11-03-general",
        "date": "2026-11-03"
      },
      "choice": {
        "id": 20931,
        "label": "Jane Doe",
        "measure_answer": null
      }
    }
  ],
  "next_cursor": "aTo5MDIxMQ"
}

That’s what labor unions endorse on California’s ballot: one row per endorser and choice, each with its contest and source. Swap categories for endorsers to pick specific groups, or narrow to one race with contest. Every endorser’s pick on one race, with the race’s choices:

GET /v1/contests/4410
curl "https://api.ballotdata.ai/v1/contests/4410?categories=labor,editorial" \
  -H "Authorization: Bearer $BALLOTDATA_API_KEY"

Lists come back as { "data": [...], "next_cursor": "…" }; see paging.

Address and geography lookups (the ballot at an address, district boundaries, representatives by location) have been retired. Choose races by state, election or contest; see what changed.

Every data endpoint, with its parameters, request samples in curl, JavaScript and Python, and an example response, is in the API reference. The stream and subscription endpoints are in the Stream API reference.

In the API docs

API docs · BallotData API