Documentation
API Endpoints
Listing Contests
Get a list of Contests, reverse ordered by election date, then government level (e.g. federal, state, city, etc.). By default, we return a paginated list all contests, which problaby isn't very useful to you, so you probably want to include some query parameters to filter the list for the elections you actually want.
HTTP Request
GET /v1/contests
Examples
- Get all the contests for a specific election:
- https://api.ballotapi.org/v1/contests?elections=a12345
- Get the ballot measures for a specific precinct:
- https://api.ballotapi.org/v1/contests?precincts=z34536482&contest_types=ballot_measure
- Search for upcoming contests for a specific term:
- https://api.ballotapi.com/v1/contests?q=soda%20tax&dates=now,future
- Get the district maps for two contests:
- https://api.ballotapi.org/v1/contests?ids=958hd92,9584h3b1&extra=contest_geos
Query Parameters
Parameter | Format | Description | Example |
---|---|---|---|
ids
|
String | A comma separated list of specific Contest ids to include in the response. |
ids=19573n3,i89i03jf
|
choice_ids
|
String | A comma separated list of specific Choice ids to include in the response. |
choice_ids=40u3ed,3-8494
|
ocd_ids
|
OCD-ID | Filter by a comma separated list of specific Open Civic Data Identifers. This searches both the Contest OCD-ID and Choice OCD-ID, so you can filter for both contest identifiers and person identifiers. |
ocd_ids=ocd-division%2F...
|
coords
|
Coordinates | Filter by a specific location point or area. For areas, if any part of a Contest's precincts overlap the query area, that Contest is included. |
coords=37.7942635,-122.3955861
|
elections
|
String | Filter by a comma separated list of specific Election ids. |
elections=a12345,a23456
|
precincts
|
String | Filter by a comma separated list of specific Precinct ids. |
precincts=49uhe3,493u03-5
|
contest_types
|
ContestType |
Filter by a comma separated list of contest types
(e.g. ballot_measure or elected_position ).
|
contest_types=ballot_measure
|
contest_levels
|
ContestLevel |
Filter by a comma separated list of contest levels
(e.g. federal , state , etc.).
|
contest_levels=city,sublocality
|
dates
|
DateTimeRange | Filter to contests occurring only within a certain datetime range. You can include shorthand names in addition to normal datetimes. |
dates=now,future |
q
|
Search | Search contests and choices for a specific string. See search strings for how to use this parameter. |
q=title%3A%22Barbra%20Lee%22
|
include
|
String |
A comma separated list of resources to include
for each Contest object response. Options are:
"election"
and
"precincts" .
|
include=precincts |
extra
|
String |
A comma separated list of extra values you want
to include in the
Options are:
|
extra=contest_geos |
Search Strings
Contests are where you can find the names of specific races and
candidates, so we let you search those fields using our generalized
search query parameter (q=...
).
Here's a general rundown of search features:
- Searches look for mentions of your search terms in these fields: Contest Title, Contest Question, Choice Title, Choice Party, and Choice Info.
- All searches are case insensitive, so you don't need to worry about whether something is capitalized.
-
You can surround a phrase with quotes (e.g.
"soda tax"
) and we will search for that specific phrase. -
You can combine the search string with other query parameters to limit
the search results (e.g. combine
q=...
withdates=...
to limit the search to elections happening only within a specific date range). -
You can search for a ballot measure name or candidate name by prefixing with
"title:" (e.g.
title:"Measure FF"
ortitle:"Barbra Lee"
). This indicates that we should only look for that term in the Contest Title for ballot measures and the Choice Title for elected positions.
Contest Geometries
If you include the
extra=contest_geos
query parameter in your request, we will merge all of
the areas of the precincts for each contest in the results
and return those merged geometries as a key-value object of Contest
id
to GeoJSON
object in the
extra
results parameter. This is useful for generating district maps for
races and ballot measures.
Example contest geometries in response:
{ "type": "response", "data": [ {"type": "contest", "id": "c239842", ...}, {"type": "contest", "id": "494y185", ...}, ... ], "next": "...", "extra": { "contest_geos": { "c239842": {"type": "MultiPolygon", ...}, "494y185": {"type": "MultiPolygon", ...}, ... }, }, "timestamp": "...", "url": "..." }
NOTE: We merge all the precincts of only the Contests in the current page of results. So, if the response is paginated, you will need to go to each page to get all the contest merged precinct geometries.
NOTE: If you want to also get the ids
of the Precincts for each of the contest geometries, use
the include=precincts
parameter to include the Precints for each contest in
the results.
Response
We will return the results of your request as a
Response object
with the data
attribute as the list of Contests.
Responses can be paginated!
Be sure to check the
next
attribute for the next page of data.
Example response:
{ "type": "response", "data": [ { "type": "contest", "id": "234-5", "ocd_id": null, "election_id": "123-4", "contest_type": "ballot_measure", "contest_level": "state", "voting_method": "choose_one", "voting_instructions": "Choose Approve or Disapprove.", "title": "Measure B: Tax Incentive Plan", "question": "Shall the Deleware constitution be updated to...", "choices": [...] }, ... ], "next": "https://api.ballotapi.org/...", "extra": {}, "timestamp": "2018-01-01T00:00:00+00:00", "url": "https://api.ballotapi.org/..." }
HTTP Response Codes
Code | Response Format | Description |
---|---|---|
200
|
Response | Successful request. |
400
|
Error Response | The query parameters you included were invalid. The Error Response will include a message describing exactly was invalid. |
429
|
N/A |
You are making too many requests to the API. Check the
Retry-After header for how many seconds to
wait until trying the request again. See our docs on
Rate Limiting.
|
500
|
N/A | An internal server error occurred. We log these errors and try to fix them quickly, so if you keep getting 500 errors for a few days, please email us. |
503
|
N/A | We are down for maintenance. Please try your request again in a few minutes. |
504
|
N/A | Your request timed out. Please try your request again in a few minutes. |