VoterGuideOS
Getting started

Find a voter’s ballot

Generate a personalized ballot from a voter address.

Most VoterGuideOS integrations should begin with the Ballots API.

Provide a voter address, and the API returns a ballot with the election, districts, races, candidates, and ballot measures relevant to that voter.

For request fields, response schemas, and implementation details, see the Full ballot API Specification.


How it works

The Ballots API accepts:

  • a voter address as street
  • an election key

The street value should include the whole address, including city, state, and ZIP code when possible.

The API returns a personalized ballot response that typically includes matched districts, races, candidates, ballot measures, and election metadata.


Example request

const response = await fetch(
  "https://www.branch.vote/api/v1/ballots",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Organization-Id": "org_123",
    },
    body: JSON.stringify({
      street: "730 Peachtree St NE, Atlanta GA, 30308",
      election: "ga-2026-general-election"
    })
  }
);

const ballot = await response.json();
import requests

response = requests.post(
    "https://www.branch.vote/api/v1/ballots",
    headers={
        "X-Organization-Id": "org_123",
        "Content-Type": "application/json",
    },
    json={
        "street": "730 Peachtree St NE, Atlanta GA, 30308",
        "election": "ga-2026-general-election",
    },
)

ballot = response.json()
curl -X POST "https://www.branch.vote/api/v1/ballots" \
  -H "X-Organization-Id: org_123" \
  -H "Content-Type: application/json" \
  -d '{
    "street": "730 Peachtree St NE, Atlanta GA, 30308",
    "election": "ga-2026-general-election"
  }'

Example response

{
  "_id": "ballot_123",
  "address": "730 Peachtree St NE, Atlanta GA, 30308",
  "addressComponents": {
    "prettyStreet": "730 Peachtree St NE, Atlanta GA, 30308",
    "city": "Atlanta",
    "state": "GA",
    "zip": 30308
  },
  "election": {
    "key": "ga-2026-general-election",
    "name": "2026 Georgia General Election"
  },
  "districts": [
    {
      "_id": "district_123",
      "name": "Atlanta City Council District 5"
    }
  ],
  "races": [
    {
      "_id": "race_456",
      "officeName": "Mayor",
      "district": {
        "_id": "district_123",
        "name": "Atlanta City Council District 5"
      },
      "candidates": [
        {
          "_id": "candidate_1",
          "name": "Jane Smith",
          "summary": "Current city council member."
        },
        {
          "_id": "candidate_2",
          "name": "John Doe",
          "summary": "Local business owner."
        }
      ]
    }
  ],
  "measures": [
    {
      "_id": "measure_1",
      "title": "Transportation Bond Referendum",
      "ballotText": "Shall the city issue bonds for transportation improvements?"
    }
  ],
  "raceChoices": [],
  "measureChoices": []
}

Unique data specific to your organization, such as candidate questionnaire responses or newsroom article links, is included in ballot responses when available.


Address matching behavior

Ballot generation depends on successfully matching a voter address to districts.

For best results:

  • provide full street addresses when possible
  • include city, state, and ZIP code in the street value when possible

If an exact district match cannot be determined, the API may return limited-support ballot content or an address-matching error depending on the address and your organization settings.


Next step

Once you have generated a personalized ballot, the next step is displaying the races, candidates, and ballot measures returned by the API.

On this page