Working with OpenStates Legislative Data
OpenStates provides comprehensive legislative data for all 50 states through standardized CSV files. This guide demonstrates how to access, enhance, and analyze this data using New Mexico as an example.
Data
Create an account. Download data locally.
Viz file structure schema details
File structure
NM_2025_csv_3LAtJwe7Zs1ldDHVVcwMRa/
├── README
└── NM/
└── 2025/
├── NM_2025_bill_actions.csv
├── NM_2025_bill_document_links.csv
├── NM_2025_bill_documents.csv
├── NM_2025_bill_sources.csv
├── NM_2025_bill_sponsorships.csv
├── NM_2025_bill_version_links.csv
├── NM_2025_bill_versions.csv
├── NM_2025_bills.csv
├── NM_2025_organizations.csv
├── NM_2025_vote_counts.csv
├── NM_2025_vote_people.csv
├── NM_2025_vote_sources.csv
└── NM_2025_votes.csv
Table Structure
1. organizations
Purpose: Legislative bodies, committees,
and other organizations
Key Fields: - id
: Unique
identifier (OCD format)
- name
: Organization name
- classification
: Type (legislature, executive,
committee, etc.)
- parent_id
: Self-referencing for hierarchical
structure
- jurisdiction_id
: Associated jurisdiction
2. bills
Purpose: Main legislative bills with
metadata
Key Fields: - id
: Unique
identifier (OCD format)
- identifier
: Bill number (e.g., “HB 267”)
- title
: Bill title
- classification
: Bill type (bill, memorial,
resolution, etc.)
- subject
: Array of subject categories
- session_identifier
: Legislative session (e.g.,
2025)
- jurisdiction
: State (New Mexico)
3. bill_actions
Purpose: Track bill progress through
legislative process
Key Fields: - id
: Unique
identifier
- bill_id
: Reference to bills table
- organization_id
: Organization taking
action
- description
: Action description
- date
: Action date
- classification
: Action type (introduction,
referral, passage, etc.)
- order
: Chronological order
4. bill_sponsorships
Purpose: Sponsors and co-sponsors of
bills
Key Fields: - id
: Unique
identifier
- name
: Sponsor name
- entity_type
: Person or organization
- person_id
: Identifier for person
(nullable)
- organization_id
: Reference to
organization
- bill_id
: Reference to bills table
- primary
: Boolean for primary sponsor
5. bill_versions
Purpose: Different versions of bills
throughout the process
Key Fields: - id
: Unique
identifier
- bill_id
: Reference to bills table
- note
: Version description
- date
: Version date
- classification
: Version type
6. bill_documents
Purpose: Documents related to bills
Key Fields: - id
: Unique
identifier
- bill_id
: Reference to bills table
- note
: Document description
- date
: Document date
- classification
: Document type
7. bill_sources
Purpose: Source URLs for bill
information
Key Fields: - id
: Unique
identifier
- bill_id
: Reference to bills table
- url
: Source URL
- note
: Description
8. bill_document_links
Purpose: Links to bill documents
Key Fields: - id
: Unique
identifier
- document_id
: Reference to bill_documents
table
- media_type
: Type of media
- url
: Link URL
9. bill_version_links
Purpose: Links to bill versions
Key Fields: - id
: Unique
identifier
- version_id
: Reference to bill_versions
table
- media_type
: Type of media
- url
: Link URL
10. votes
Purpose: Vote events on bills
Key Fields: - id
: Unique
identifier (OCD format)
- identifier
: Vote identifier
- motion_text
: Motion description
- motion_classification
: Vote type
- start_date
: Vote date
- result
: Vote outcome (pass, fail, etc.)
- organization_id
: Voting body
- bill_id
: Associated bill
- jurisdiction
: State
- session_identifier
: Session
11. vote_counts
Purpose: Aggregate vote counts by
option
Key Fields: - id
: Unique
identifier
- vote_event_id
: Reference to votes table
- option
: Vote option (yes, no, abstain,
etc.)
- value
: Count of votes
12. vote_people
Purpose: Individual vote records
Key Fields: - id
: Unique
identifier
- vote_event_id
: Reference to votes table
- option
: Individual’s vote
- voter_name
: Voter’s name
- voter_id
: Voter’s unique identifier
(nullable)
13. vote_sources
Purpose: Source URLs for vote
information
Key Fields: - id
: Unique
identifier
- vote_event_id
: Reference to votes table
- url
: Source URL
- note
: Description
Key Relationships
Primary Relationships
- bills → bill_actions
(one-to-many)
- bills →
bill_sponsorships (one-to-many)
- bills → bill_versions
(one-to-many)
- bills → bill_documents
(one-to-many)
- bills → votes
(one-to-many)
- organizations → bills
(one-to-many via sponsorships)
- votes → vote_people
(one-to-many)
- votes → vote_counts (one-to-many)
Legislators
Per a given congress, or year, OS folks generate a legislators file …
Romero, GA == Representative G. Andrés Romero - (D) · District: 10 – ocd-person/5cf6976d-e616-4579-a194-ec3c37260ebd
Romero, A. == Representative Andrea Romero - (D). Romero. District: 46 – ocd-person/ed0ba54a-4fc3-4c50-aa0d-f74b1f0e86f6
Garcia, M. == Representative Martha Garcia - (D) · District: 6 – ocd-person/fb0443f9-b6d7-4b3b-a87e-0d8b143ed64b
García, MP == Representative Miguel P. García - (D) · District: 14 – ocd-person/3363aa83-2490-4631-b04b-9a52fdbad14b
LOPEZ and MUNOZ in the Senate – all caps + daicritics – ?? –
LOPEZ == ocd-person/ecc60fc8-8598-4650-8a55-6e91d24e991e MUNOZ == ocd-person/b4c20aea-b56c-4a19-a89a-788c53d995d7
2. legislators
Purpose: Individual legislators with
personal and contact information Key Fields:
- id
: Unique identifier (OCD format) -
name
: Full name of legislator -
current_party
: Political party affiliation -
current_district
: Legislative district number -
current_chamber
: Chamber (upper/lower) -
given_name
: First name -
family_name
: Last name - gender
:
Gender identification - email
: Contact email
address - biography
: Legislative biography -
birth_date
: Date of birth -
death_date
: Date of death (if applicable) -
image
: URL to official photo -
links
: URLs to legislator pages -
sources
: Source URLs for information -
capitol_address
: Capitol office address -
capitol_voice
: Capitol office phone -
capitol_fax
: Capitol office fax -
district_address
: District office address -
district_voice
: District office phone -
district_fax
: District office fax -
twitter
: Twitter handle - youtube
:
YouTube handle - instagram
: Instagram handle -
facebook
: Facebook handle -
wikidata
: Wikidata identifier
Committee Membership
Committee membership information is not made available in csv – instead, this info is maintained on GitHub… collated here.
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(httr)
library(yaml)
# Step 1: Use GitHub API to get file list
api_url <- "https://api.github.com/repos/openstates/people/contents/data/nm/committees"
res <- GET(api_url)
stop_for_status(res)
# Step 2: Extract raw download URLs
files <- content(res)
yaml_urls <- vapply(files, function(x) x$download_url, character(1))
# Step 3: Read YAML content into R
yaml_objects <- lapply(yaml_urls, function(url) {
r <- GET(url)
stop_for_status(r)
txt <- content(r, as = "text", encoding = "UTF-8")
yaml::yaml.load(txt)
})
## data.table 1.17.2 using 24 threads (see ?getDTthreads). Latest news: r-datatable.com
##
## Attaching package: 'data.table'
##
## The following objects are masked from 'package:dplyr':
##
## between, first, last
# Example: extract from one record
extract_committee_members <- function(x) {
if (!length(x$members)) return(NULL)
data.table(
committee_id = x$id,
committee_name = x$name,
committee_classification = x$classification,
chamber = x$chamber,
member_name = vapply(x$members, function(m) m$name, character(1)),
member_role = vapply(x$members, function(m) m$role, character(1)),
person_id = vapply(x$members, function(m) m$person_id, character(1))
)
}
# Apply across all objects
dt_members <- rbindlist(
lapply(yaml_objects, extract_committee_members),
use.names = TRUE,
fill = TRUE
)
committee_id | committee_name | committee_classification | chamber | member_name | member_role | person_id |
---|---|---|---|---|---|---|
ocd-organization/c5890a48-0349-4f4c-aca8-b3dc9ad30897 | Capitol Buildings Planning Commission | committee | legislature | Javier Martínez | co-chair | ocd-person/221a42af-f54f-4e66-b648-9b0028165595 |
ocd-organization/c5890a48-0349-4f4c-aca8-b3dc9ad30897 | Capitol Buildings Planning Commission | committee | legislature | Bill Sharer | member | ocd-person/7a7be318-78b1-49c6-bd98-f2b9b7476372 |
ocd-organization/c5890a48-0349-4f4c-aca8-b3dc9ad30897 | Capitol Buildings Planning Commission | committee | legislature | Gail Armstrong | member | ocd-person/9564298b-dc55-4037-8205-5eca1c2063dc |
ocd-organization/c5890a48-0349-4f4c-aca8-b3dc9ad30897 | Capitol Buildings Planning Commission | committee | legislature | Mimi Stewart | member | ocd-person/f1144347-0a16-43e4-97b9-01308a890631 |
ocd-organization/9807242f-d304-4548-b418-ec3efdee2e4d | Courts, Corrections and Justice | committee | legislature | Joe Cervantes | chair | ocd-person/14f0186e-bf9b-46aa-aa00-1ccc8f58490b |
ocd-organization/9807242f-d304-4548-b418-ec3efdee2e4d | Courts, Corrections and Justice | committee | legislature | Chris Chandler | vice chair | ocd-person/6ecab682-9ccf-4777-940d-afa418b601b8 |
your_project/
├── openstates_data/
│ ├── NM_2025_bills.csv
│ ├── NM_2025_votes.csv
│ └── [other CSV files]
├── committee_data.csv