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

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

  1. billsbill_actions (one-to-many)
  2. billsbill_sponsorships (one-to-many)
  3. billsbill_versions (one-to-many)
  4. billsbill_documents (one-to-many)
  5. billsvotes (one-to-many)
  6. organizationsbills (one-to-many via sponsorships)
  7. votesvote_people (one-to-many)
  8. votesvote_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.

library(dplyr)
## 
## 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)
})
library(data.table)
## 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
)
dt_members |> head() |> knitr::kable() #DT::datatable(rownames = F)
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