Skip to contents

Prerequisites

Before scraping data you need a working Python environment. If you have not done so yet, follow the steps in the Python setup vignette:

# One-time setup (downloads ~100-200 MB the first time)
downballot_install_python()

At the start of each R session:


The single entry point: scrape_elections()

All data retrieval flows through one function:

scrape_elections(state, ...)

The scraper is selected automatically based on state — you never need to specify a backend by name:

Priority Condition Scraper used
1 state is North Carolina North Carolina State Board of Elections scraper (2000–present)
2 state is Connecticut Connecticut CTEMS scraper (2016–present)
3 state is Georgia Georgia Secretary of State scraper (2000–present)
4 state is Utah Utah election results scraper (2023–present)
5 state is Indiana Indiana voters portal scraper (2019–present)
6 state is Louisiana Louisiana Secretary of State scraper (1982–present)
7 All other states ElectionStats multi-state scraper

Data availability

Use db_available_years() to check available year ranges programmatically:

# All sources
db_available_years()

# Filter to one state
db_available_years(state = "Virginia")
Source State Start year End year
ElectionStats Vermont 1789 2024
ElectionStats Virginia 1789 2025
ElectionStats Colorado 1902 2024
ElectionStats Massachusetts 1970 2026
ElectionStats New Hampshire 1970 2024
ElectionStats Idaho 1990 2024
ElectionStats New York 1994 2024
ElectionStats New Mexico 2000 2024
ElectionStats South Carolina 2008 2025
North Carolina State Board of Elections North Carolina 2000 present
Connecticut CTEMS Connecticut 2016 present
Georgia Secretary of State Georgia 2000 present
Utah elections site Utah 2023 present
Indiana voters portal Indiana 2019 present
Louisiana Secretary of State Louisiana 1982 present

To see which states are supported by the ElectionStats scraper:

db_list_states("election_stats")
#> [1] "Colorado"        "Idaho"           "Massachusetts"   "New Hampshire"
#> [5] "New Mexico"      "New York"        "South Carolina"  "Vermont"
#> [9] "Virginia"

Choosing the right scraper

Note on level: The level argument selects the constituency level of the returned results — i.e., the geographic unit at which votes are tabulated. For example, level = "state" returns state-level constituency (statewide) results, level = "county" returns county-level constituency results, and level = "precinct" returns precinct-level constituency results. This is not the same as office level (Federal / State / Local).

Goal Call
Candidate + vote totals for Colorado, Massachusetts, New Hampshire, Idaho, Vermont (classic) scrape_elections(state = "virginia", ...)
Precinct-level results for Colorado, Massachusetts, Idaho (classic) scrape_elections(state = "colorado", year_from = 2022, year_to = 2022, level = "precinct")
Candidate + vote totals for South Carolina, New Mexico, Virginia, New York (Playwright) scrape_elections(state = "south_carolina", ...)
Precinct-level results for South Carolina, New Mexico, Virginia (v2 CSV API) scrape_elections(state = "new_mexico", year_from = 2024, year_to = 2024, level = "precinct")
North Carolina precinct-level local results scrape_elections(state = "north_carolina", year_from = 2025, year_to = 2025)
Connecticut statewide + town results scrape_elections(state = "connecticut", year_from = 2024, year_to = 2024)
Connecticut statewide totals only (faster) scrape_elections(state = "connecticut", year_from = 2024, year_to = 2024, level = "state")
Georgia statewide + county + precinct results scrape_elections(state = "georgia", year_from = 2024, year_to = 2024)
Georgia statewide + county only (faster) scrape_elections(state = "georgia", year_from = 2024, year_to = 2024, level = "county")
Georgia with vote-method breakdown scrape_elections(state = "georgia", year_from = 2024, year_to = 2024, include_vote_methods = TRUE)
Georgia precinct-level only scrape_elections(state = "georgia", year_from = 2024, year_to = 2024, level = "precinct")
Utah statewide + county + precinct results scrape_elections(state = "utah", year_from = 2024, year_to = 2024)
Utah statewide + county only (faster) scrape_elections(state = "utah", year_from = 2024, year_to = 2024, level = "county")
Utah statewide only (fastest) scrape_elections(state = "utah", year_from = 2024, year_to = 2024, level = "state")
Utah precinct-level only scrape_elections(state = "utah", year_from = 2024, year_to = 2024, level = "precinct")
Indiana statewide + county General Election results scrape_elections(state = "indiana", year_from = 2024, year_to = 2024)
Indiana statewide only (faster) scrape_elections(state = "indiana", year_from = 2022, year_to = 2022, level = "state")
Louisiana statewide + parish results scrape_elections(state = "louisiana", year_from = 2024, year_to = 2024)
Louisiana statewide only (faster; skips parish scraping) scrape_elections(state = "louisiana", year_from = 2023, year_to = 2023, level = "state")

Next: analyzing the data

Once you have a scraped data frame, the Example analyses vignette walks through worked example questions — wins by party, closest races, down-ballot drop-off, county-level variation, and cross-state comparisons — with tidyverse code you can adapt to your own scrapes.


Detailed articles

Each scraper has its own article with full argument documentation, worked examples, and column descriptions (available on the package website):

  • ElectionStats states — Virginia, Massachusetts, Colorado, New Hampshire, Idaho, Vermont (classic) + South Carolina, New Mexico, New York (Playwright); candidate + county + precinct results
  • North Carolina — North Carolina State Board of Elections; precinct-level results
  • Connecticut — Connecticut CTEMS; statewide + town results, 2016–present
  • Georgia — Georgia Secretary of State; statewide + county + precinct results, 2000–present
  • Utah — Utah elections site; statewide + county + precinct results, 2023–present
  • Indiana — Indiana voters portal; statewide + county General Election results, 2019–present
  • Louisiana — Louisiana Secretary of State; statewide + parish results, 1982–present

Performance tips

  • Start small — test with a single year and state before requesting large date ranges.
  • Playwright states are slower — South Carolina, New Mexico, and New York launch a headless browser for each scrape. Expect several seconds per year.
  • Parallel scraping is on by default for classic (requests-based) ElectionStats states. Pass parallel = FALSE to disable.
  • Be polite — built-in delays are intentional. Do not reduce or disable them; excessive requests may result in temporary IP blocks.