Democracy Works Contests API

The Contests API from Democracy Works — 1 operation retrieving a single contest by id, with its candidate list, seats up for election, ranked-choice rules, partisan-primary rules and cancellation status.

Operations 1

GET /contests Contest #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/democracy-works-contests-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

democracy-works-contests-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Democracy Works Contests API
  version: '2.0'
  description: '# Introduction


    The Democracy Works Elections API provides your application with comprehensive elections data and voting guidance, surfacing our unparalleled coverage of upcoming local, state, and federal elections.'
servers:
- url: https://api.democracy.works/v2
tags:
- name: Contests
paths:
  /contests:
    get:
      operationId: getContest
      summary: Contest
      description: This endpoint gets one contest by `id`.
      security:
      - ApiKeyAuth: []
      parameters:
      - name: id
        in: path
        schema:
          type: string
          description: Hash identifier of the contest to get.
          example: co_682d473ab8a590c2f1ed2d4fd8dd11c49a44b62f
        required: true
      responses:
        '200':
          description: Contest fetched by query.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/contest'
              examples:
                sampleContestsResponse:
                  $ref: '#/components/examples/contests'
        '400':
          $ref: '#/components/responses/badRequestError'
        '404':
          description: Not Found Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/errors'
              example:
                status: 404
                message:
                - Contest not found.
        '429':
          $ref: '#/components/responses/tooManyRequestsError'
        '500':
          $ref: '#/components/responses/internalServerError'
      tags:
      - Contests
components:
  examples:
    contests:
      summary: Sample contests response
      description: 'This is **fictional** data to provide examples of fields values.

        '
      value:
        data:
          contests:
            id: co_682d473ab8a590c2f1ed2d4fd8dd11c49a44b62f
            name: AC Transit District Board of Directors Ward 6
            title: null
            body: null
            level: local
            branch: legislative
            districtName: AC Transit District Ward 6
            districtType: specialDistrictSubdivision
            contestType: regular
            ocdId: ocd-division/country:us/state:ca/transit_district:alameda-contra_costa/district:6
            seatsUpForElection: 1,
            rankedChoice: false
            rankedChoiceExplainerURL: null
            rankedChoiceRankNumber: null
            hasPrimary: false
            generalDate: null
            primaryDate: null
            partisanPrimary: null
            partisanPrimaryExplainerUrl: null
            partisanPrimaryExplainerEn: null
            partisanPrimaryExplainerEs: null
            cancelled: null
            aboutOffice: null
            candidates:
            - id: can_07e636ccd8ca58886d6578b4006233f5b2153b8f
              fullName: Shonda Goward
              firstName: Shonda
              lastName: Goward
              partyAffiliation:
              - Nonpartisan
              isIncumbent: false
              isWriteIn: false
              ballotpediaUrl: https://ballotpedia.org/Shonda_Goward
              status: lost
              runningMateFullName: null
              runningMateTitle: null
              rankedChoiceVotingRound: null
              endorsementCount: 1
              contact:
                campaign:
                  email: shonda@gowardforactransit.com
                  website: http://www.gowardforactransit.com
                  facebook: null
                  twitter: null
                  instagram: null
                  youtube: null
                  mailingAddress: 30042 Mission Blvd
                  Ste 121 PMB 205: null
                  Hayward: null
                  CA 94544: null
                  phone: 510-646-0845
                personal:
                  website: null
                  facebook: null
                  twitter: shondagoward
                  instagram: https://www.instagram.com/sixthregion/
                  youtube: null
                  linkedIn: https://www.linkedin.com/in/shondagoward/
            - id: can_92800009b57ea6d51a701ebaec4ce10be78494f3
              fullName: Jesse Lee Gunn
              firstName: Jesse
              lastName: Gunn
              partyAffiliation:
              - Nonpartisan
              isIncumbent: false
              isWriteIn: false
              ballotpediaUrl: https://ballotpedia.org/Jesse_Lee_Gunn
              status: lost
              runningMateFullName: null
              runningMateTitle: null
              rankedChoiceVotingRound: null
              endorsementCount: 1
              contact:
                campaign:
                  email: jg4act@gmail.com
                  website: https://www.jesse2024.com/
                  facebook: https://www.facebook.com/jesse4transit
                  twitter: null
                  instagram: https://www.instagram.com/jesse4transit
                  youtube: null
                  mailingAddress: 510 Schafer Road Hayward CA 94544
                  phone: 510-512-4236
                personal:
                  website: null
                  facebook: https://www.facebook.com/jesse4transit
                  twitter: jessegunnmath
                  instagram: null
                  youtube: https://www.youtube.com/@jessegunn5994
                  linkedIn: https://www.linkedin.com/in/jesse4transit/
  responses:
    internalServerError:
      description: InternalServerError
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/errors'
          example:
            status: 500
            message:
            - Something went wrong.
    badRequestError:
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/errors'
          example:
            status: 400
            message:
            - Something has gone wrong parsing your request. Please refer to our documentation at https://developers.democracy.works/api/v2 to confirm all required fields are present and all fields are formatted correctly.
    tooManyRequestsError:
      description: TooManyRequestsError
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/gatewayErrors'
          example:
            message: Too Many Requests
  schemas:
    gatewayErrors:
      type: object
      properties:
        message:
          type: string
      required:
      - message
    errors:
      type: object
      properties:
        status:
          type: integer
        message:
          type: array
      required:
      - status
      - message
    candidate:
      description: A representation of a candidate.
      type: object
      required:
      - id
      - fullName
      - firstName
      - lastName
      - partyAffiliation
      - isWriteIn
      properties:
        id:
          type: string
          description: The ID of the candidate.
        fullName:
          type: string
          description: The full name of the candidate.
        firstName:
          type: string
          description: The first name of the candidate.
        lastName:
          type: string
          description: The last name of the candidate.
        partyAffiliation:
          type: array
          description: Describes the party affiliation of the candidate.
          items:
            type: string
        isIncumbent:
          type: boolean
          description: Indicates whether a candidate is an incumbent.
        isWriteIn:
          type: boolean
          description: Indicates whether a candidate is a write-in candidate.
        ballotpediaUrl:
          type: string
          description: The URL of the candidate's Ballotpedia page.
        status:
          type: string
          description: The status of the candidate in that contest.
          enum:
          - won
          - lost
          - advanced
          - declared
          - disqualified
          - onBallot
          - withdrew
          - notable
          - acclaimed
          - withdrewStillOnBallot
        runningMateFullName:
          type: string
          description: The full name of the candidate's running mate.
        runningMateTitle:
          type: string
          description: The title of the candidate's running mate.
        rankedChoiceVotingRound:
          type: number
          description: RCV results are reported in “rounds” of calculations. Ballotpedia reports each round of these results, so a candidate in an RCV will have a row for each round of calculation in that stage. The first round of results reported will have this attribute = 1. Rounds will count up until the final round.
        endorsementCount:
          type: number
          description: The number of endorsements available for this candidate.
        contact:
          type: object
          properties:
            campaign:
              type: object
              properties:
                email:
                  type: string
                  description: The candidate’s campaign email address.
                website:
                  type: string
                  description: The candidate’s campaign website.
                facebook:
                  type: string
                  description: The candidate’s campaign Facebook.
                twitter:
                  type: string
                  description: The candidate’s campaign Twitter.
                instagram:
                  type: string
                  description: The candidate’s campaign Instagram.
                youtube:
                  type: string
                  description: The candidate’s campaign YouTube.
                mailingAddress:
                  type: string
                  description: The candidate’s campaign mailing address.
                phone:
                  type: string
                  description: The candidate’s campaign phone number.
            personal:
              type: object
              properties:
                website:
                  type: string
                  description: The candidate’s personal website.
                facebook:
                  type: string
                  description: The candidate’s personal Facebook.
                twitter:
                  type: string
                  description: The candidate’s personal Twitter.
                instagram:
                  type: string
                  description: The candidate’s personal Instagram.
                youtube:
                  type: string
                  description: The candidate’s personal YouTube.
                linkedIn:
                  type: string
                  description: The candidate’s personal LinkedIn.
    contest:
      description: Information on the race for the specific office up for election, including the list of candidates and candidate information.
      type: object
      required:
      - id
      - name
      - level
      - districtName
      - ocdId
      - seatsUpForElection
      - candidates
      properties:
        id:
          type: string
          description: The ID of the contest.
        name:
          type: string
          description: 'The name of the office  (ex: “President”).'
        title:
          type: string
          description: Human readable title of the office (e.g. Senator)
        body:
          type: string
          description: Label of legislative or judicial body to which the contest belongs
        level:
          type: string
          description: The level of the contest.
          enum:
          - federal
          - state
          - local
        branch:
          type: string
          description: The branch of government of the office.
          enum:
          - executive
          - judicial
          - legislative
        districtName:
          type: string
          description: The name of the district that elects the office.
        districtType:
          type: string
          description: The type of district that elects the office.
          enum:
          - cityTown
          - cityTownSubdivision
          - congress
          - county
          - countySubdivision
          - judicialDistrict
          - judicialDistrictSubdivision
          - schoolDistrict
          - schoolDistrictSubdivision
          - specialDistrict
          - specialDistrictSubdivision
          - state
          - stateLegislativeLower
          - stateLegislativeUpper
          - stateSubdivision
          - township
        contestType:
          type: string
          description: The type of contest.
          enum:
          - regular
          - special
          - recall
        ocdId:
          type: string
          description: The OCD-ID of the contest.
        seatsUpForElection:
          type: string
          description: The number of seats up for election.
        rankedChoice:
          type: boolean
          description: If the contest is conducted by ranked choice voting (RCV), then TRUE; else FALSE.
        rankedChoiceExplainerURL:
          type: string
          description: Link to state or local election administrator website explaining how ranked choice voting works.
        rankedChoiceRankNumber:
          type: number
          description: Number of candidates a voter can rank on a ballot in a Ranked Choice Election.
        hasPrimary:
          type: boolean
          description: For a general election, indicates if an associated primary election exists.
        primaryDate:
          type: string
          description: For a general election, provides the date of the associated primary election.
        generalDate:
          type: string
        partisanPrimary:
          type: string
        partisanPrimaryExplainerUrl:
          type: string
          description: URL where voter can learn more about how to vote in the party primary contest.
        partisanPrimaryExplainerEn:
          type: string
          description: English-language sentence explaining to voters how to vote in the party primary contest.
        partisanPrimaryExplainerEs:
          type: string
          description: Spanish-language sentence explaining to voters how to vote in the party primary contest.
        partisanPrimaryExplainerSharedId:
          type: string
          description: Hash for all contests (associated with the election) sharing the same guidance.
        cancelled:
          type: boolean
          description: TRUE if contest does not appear on ballot due to a cancellation. Contests may be cancelled if the number of candidates filed is less than or equal to the number of positions up for election. Not all jurisdictions cancel contests under these circumstances as write-in votes may be allowed in some case
        aboutOffice:
          type: string
          description: A brief summary of the role and responsibilities associated with an office.
        candidates:
          type: array
          items:
            $ref: '#/components/schemas/candidate'
          description: A list of candidates running for election for the contest.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY