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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| id | Unique identifier |
| bill_id | Reference to bills table |
| url | Source URL |
| note | Description |
8. bill_document_links
Purpose: Links to bill documents
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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
| Field | Description |
|---|---|
| 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.
library(dplyr)
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)
# 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 |>
DT::datatable(
rownames = FALSE,
options = list(
scrollX = TRUE,
autoWidth = TRUE,
columnDefs = list(list(width = "100%", targets = "_all"))
),
width = "100%"
)your_project/
├── openstates_data/
│ ├── NM_2025_bills.csv
│ ├── NM_2025_votes.csv
│ └── [other CSV files]
├── committee_data.csv