Data dictionaries

Endorser agreement

How often other endorsers took the same side as one endorser, over the contests both took a position in.

Returned by
GET /v1/endorsers/{slug}/agreement
Shapes
The full record is in GET /v1/endorsers/{slug}/agreement. The shorter forms in each endorser compared leave some fields out; a field that isn’t in every form says where it is.

How it connects

  • Worked out from both endorsers’ endorsements in the same contests; GET /v1/contests/{id} shows the positions themselves.
  • Each compared endorser is an Endorser in brief; use its slug with GET /v1/endorsers/{slug} or in with=.

Good to know

  • Positions are compared by top picks: the first choice in a ranked-choice contest, the whole slate in a vote-for-N contest, the Yes or No on a measure.
  • agreed + partly_agreed + disagreed is always shared_contests. partly_agreed only happens in vote-for-N contests.
  • Endorsers with fewer than min_shared contests in common (3 unless you say) are left out, because a rate over one or two contests says little.
  • The comparison counts every contest in common that you can read; narrow it with elections, states, contest_kinds or stages.

Fields

FieldTypeMeaningExample
endorserEndorserWho made an endorsement.—
contestsintegerContests this endorser took a position in, with the filters applied.Only in GET /v1/endorsers/{slug}/agreement.84
comparedarray of Endorser agreementOther endorsers who took positions in the same contests, most contests in common first (then highest agreement).Only in GET /v1/endorsers/{slug}/agreement.—
shared_contestsintegerContests both endorsers took a position in.Only in each endorser compared.41
agreedintegerOf those, contests where both made the same top picks (the same candidate, the same slate, the same answer on a measure).Only in each endorser compared.22
partly_agreedintegerContests where their picks overlap but differ: part of the same vote-for-N slate.Only in each endorser compared.3
disagreedintegerContests where they have no top pick in common.Only in each endorser compared.16
agreement_ratenumberagreed / shared_contests, 0 to 1, to three places.Only in each endorser compared.0.537

Download every dictionary as CSV or JSON.

Sample (JSON)

One endorser agreement as the API returns it, in GET /v1/endorsers/{slug}/agreement. More in the sample data.

{
  "endorser": {
    "id": 512,
    "slug": "sf-labor-council",
    "name": "San Francisco Labor Council",
    "category": {
      "slug": "labor",
      "name": "Labor"
    },
    "state": "CA"
  },
  "contests": 84,
  "compared": [
    {
      "endorser": {
        "id": 88,
        "slug": "sf-chronicle",
        "name": "San Francisco Chronicle",
        "category": {
          "slug": "editorial",
          "name": "Voter guides & editorial boards"
        },
        "state": "CA"
      },
      "shared_contests": 41,
      "agreed": 22,
      "partly_agreed": 3,
      "disagreed": 16,
      "agreement_rate": 0.537
    },
    {
      "endorser": {
        "id": 97,
        "slug": "sf-democratic-party",
        "name": "San Francisco Democratic Party",
        "category": {
          "slug": "party",
          "name": "Political parties"
        },
        "state": "CA"
      },
      "shared_contests": 38,
      "agreed": 33,
      "partly_agreed": 2,
      "disagreed": 3,
      "agreement_rate": 0.868
    }
  ]
}

CSV: GET /v1/endorsers/{slug}/agreement?format=csv

One row per endorser compared, most contests in common first. An empty cell is a null or a value that doesn’t apply. The next page’s cursor comes in the X-Next-Cursor header.

ColumnTypeMeaningExample
endorser_slugstringEndorser slug.From endorser.slug in the JSON.sf-labor-council
endorser_contestsintegerContests this endorser took a position in, with the filters applied.From contests in the JSON.84
other_endorser_idintegerEndorser id.From compared[].endorser.id in the JSON.88
other_endorser_slugstringEndorser slug.From compared[].endorser.slug in the JSON.sf-chronicle
other_endorser_namestringEndorser name.From compared[].endorser.name in the JSON.San Francisco Chronicle
other_endorser_categorystringCategory slug, used in categories= filters.editorial, labor, environment, business, party, club, community, officials, … meaningsFrom compared[].endorser.category.slug in the JSON.editorial
other_endorser_statestringcan be emptyTwo capital letters (USPS code)Home state; null for national endorsers.From compared[].endorser.state in the JSON.CA
shared_contestsintegerContests both endorsers took a position in.From compared[].shared_contests in the JSON.41
agreedintegerOf those, contests where both made the same top picks (the same candidate, the same slate, the same answer on a measure).From compared[].agreed in the JSON.22
partly_agreedintegerContests where their picks overlap but differ: part of the same vote-for-N slate.From compared[].partly_agreed in the JSON.3
disagreedintegerContests where they have no top pick in common.From compared[].disagreed in the JSON.16
agreement_ratenumberagreed / shared_contests, 0 to 1, to three places.From compared[].agreement_rate in the JSON.0.537

Sample (CSV)

The same records as the JSON sample, as format=csv returns them.

endorser_slug,endorser_contests,other_endorser_id,other_endorser_slug,other_endorser_name,other_endorser_category,other_endorser_state,shared_contests,agreed,partly_agreed,disagreed,agreement_rate
sf-labor-council,84,88,sf-chronicle,San Francisco Chronicle,editorial,CA,41,22,3,16,0.537
sf-labor-council,84,97,sf-democratic-party,San Francisco Democratic Party,party,CA,38,33,2,3,0.868
Endorser agreement data dictionary · BallotData API