What it covers
The Ballotpedia state elections scraper collects federal, state, and
local candidate listings from Ballotpedia’s per-state election pages
(e.g. https://ballotpedia.org/Maine_elections,_2024). Use
office = "state_elections" to activate it.
Each page has three subsections — Federal Candidates, State
Candidates, Local Candidates — which you can filter with the
election_level argument.
Coverage: 2024 and 2025 page layouts are supported. Not all states have a Ballotpedia page for every year.
Vote counts require
mode = "results", which follows each contest URL (one extra request per race). Use the defaultmode = "listings"for a fast candidate roster without vote data.
Arguments
| Argument | Default | Description |
|---|---|---|
office |
— | Must be "state_elections"
|
state |
required | State name, title-case (e.g. "Maine",
"Pennsylvania") |
year |
NULL |
Single election year (e.g. 2024). Required for
mode = "results". |
election_level |
"all" |
Candidate tier to return — see below |
mode |
"listings" |
What to return — see below |
start_year |
2024 |
Earliest year for multi-year listing scrape when year
is NULL
|
end_year |
NULL |
Latest year (default: current calendar year) |
Examples
All candidates for a state — fast listing
maine_2024 <- scrape_elections(
state = "Maine",
office = "state_elections",
year = 2024
)
maine_2024 %>%
select(level, office, jurisdiction, district, candidate, party, status) %>%
arrange(level, office)Federal candidates only
scrape_elections(
state = "Pennsylvania",
office = "state_elections",
year = 2024,
election_level = "federal"
) %>%
select(office, jurisdiction, district, candidate, party, status)Local candidates only
scrape_elections(
state = "Maine",
office = "state_elections",
year = 2024,
election_level = "local"
) %>%
select(jurisdiction, office, district, candidate, party, status) %>%
arrange(jurisdiction, office)Full results with vote counts
mode = "results" follows each contest link and returns
votes and winner/incumbent flags:
maine_results <- scrape_elections(
state = "Maine",
office = "state_elections",
year = 2024,
mode = "results"
)
# Winners only, sorted by vote share
maine_results %>%
filter(is_winner) %>%
arrange(desc(pct)) %>%
select(level, office, jurisdiction, district, candidate, party, pct, votes)Local results with vote counts
scrape_elections(
state = "Maine",
office = "state_elections",
year = 2024,
election_level = "local",
mode = "results"
) %>%
filter(is_winner) %>%
select(jurisdiction, office, district, candidate, party, pct, votes) %>%
arrange(jurisdiction, office)State-level incumbents running for re-election
scrape_elections(
state = "Virginia",
office = "state_elections",
year = 2025,
election_level = "state",
mode = "results"
) %>%
filter(is_incumbent) %>%
select(office, district, candidate, party, is_winner, pct, votes)Multi-year listing (2024–2025)
Use start_year / end_year when
year is omitted:
multi <- scrape_elections(
state = "Virginia",
office = "state_elections",
start_year = 2024,
end_year = 2025
)
multi %>%
group_by(year, level) %>%
summarise(n_candidates = n(), .groups = "drop")Columns returned
mode = "listings"
-
year,state,level(federal / state / local) -
contest_name— raw office text as shown on Ballotpedia -
contest_url— link to the individual election page -
jurisdiction— parsed geographic area (e.g."Maine","Augusta") -
office— parsed role (e.g."U.S. Senate","City Council") -
district— parsed sub-race qualifier (e.g."District 1","At-large") -
candidate,ballotpedia_url,party,status(e.g."Won General","Lost Primary")