FRA rail safety data
FRA rail safety data
Federal Railroad Administration records combine reportable rail-equipment accidents with current and historical highway-rail crossing inventory data, exposed as JSON and CSV through the DOT data portal. Accident fields cover date, railroad, location, accident type, cause, damage and hazardous-material involvement; crossing fields cover location, track and road characteristics, warning devices, traffic and revision status, with no key required.
Coverage
The accident series is nationwide from January 1975 through August 2026, while current and historical crossing records include revision dates from 1970 through October 2026. Checked totals were 225,558 accident records, 438,914 current-inventory records and 5,046,106 historical-inventory records; the FRA landing page said its accident and incident datasets ran through August 31, 2026.
Verdict
This is a safety and infrastructure signal for derailments, collisions, damage, causes and changing crossing characteristics across the U.S. rail system. Accident reports can flag localized operational disruption or hazardous-material exposure, while inventory records add crossing context. The latest accident month lagged verification by two months, and reporting thresholds mean the accident table does not represent every rail event. Crossing records are revised over time, so retain revision dates and distinguish current from historical inventory.
Get the free weekly email
Free weekly email of newly verified free data. Unsubscribe by emailing us.
By entering your email and clicking Subscribe, you agree to receive the Signal Lab weekly email from Quantum Data Technologies Ltd., 3200-650 West Georgia Street, Vancouver, BC V6B 4P7, Canada (signal-lab@qdt.ai). You can unsubscribe at any time: reply "unsubscribe" to any email or write to signal-lab@qdt.ai. See our Privacy Policy.
Use in your agent
Load recent FRA accidents and crossing revisions into Parquet. Checked against the provider's documentation on Nov 1, 2026.
Access
- No account or key. DOT exposes both FRA tables through public JSON endpoints.
- This bounded example requests 2026 accidents and the first 5,000 crossing revisions dated from October 1, 2026.
Request
curl 'https://data.transportation.gov/resource/85tf-25kj.json?$where=date%20%3E=%20%272026-01-01T00:00:00.000%27&$limit=5000'Format
JSON arrays. Accident rows include event date, railroad, accident number and type, state, county, damage and cause; crossing rows include revision date, crossing ID, railroad, location, position, coordinates and closure status.
Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
"""Recent FRA rail accidents and crossing-inventory revisions -> Parquet. No key."""
import requests
import pandas as pd
HEADERS = {"User-Agent": "SignalLabCheck/1.0"}
ACCIDENTS = "https://data.transportation.gov/resource/85tf-25kj.json"
CROSSINGS = "https://data.transportation.gov/resource/m2f8-22s6.json"
accident_params = {
"$select": "date,reportingrailroadcode,accidentnumber,accidenttype,stateabbr,countyname,totaldamagecost,primaryaccidentcause",
"$where": "date >= '2026-01-01T00:00:00.000'",
"$order": "date",
"$limit": 5000,
}
crossing_params = {
"$select": "revisiondate,crossingid,railroadcode,statename,countyname,cityname,crossingposition,latitude,longitude,crossingclosed",
"$where": "revisiondate >= '2026-10-01T00:00:00.000'",
"$order": "revisiondate",
"$limit": 5000,
}
ra = requests.get(ACCIDENTS, params=accident_params, headers=HEADERS, timeout=60)
ra.raise_for_status()
rc = requests.get(CROSSINGS, params=crossing_params, headers=HEADERS, timeout=60)
rc.raise_for_status()
accidents = pd.DataFrame(ra.json())
crossings = pd.DataFrame(rc.json())
accidents["date"] = pd.to_datetime(accidents["date"], utc=True)
crossings["revisiondate"] = pd.to_datetime(crossings["revisiondate"], utc=True)
accidents.to_parquet("fra_rail_accidents_2026.parquet", index=False)
crossings.to_parquet("fra_crossing_revisions_2026_10.parquet", index=False)
print(len(accidents), "accidents", accidents["date"].min().date(), "to", accidents["date"].max().date(),
"|", len(crossings), "crossing revisions", crossings["revisiondate"].min().date(), "to",
crossings["revisiondate"].max().date())Run by us on 2026-11-01 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 1409 accidents 2026-01-01 to 2026-08-31 | 5000 crossing revisions 2026-10-01 to 2026-10-07
Limits
- Rate limit: Not stated.
- The example's 5,000-row crossing result is a bounded extract, not every October revision.
- The FRA landing page said accident and incident datasets currently include data through August 31, 2026.
Quirks
- Multiple railroads can file records for one event; use railroad code plus accident number and year as the reporting-record identity.
- Crossing inventory dates describe record revisions, not crossing construction dates.
- Use the historical inventory for prior versions and the current table for the latest record per crossing.
Terms and attribution
- The DOT metadata labels the accident table Public Domain U.S. Government and the current crossing table Public Domain.
- No attribution requirement was stated in the checked dataset metadata.
Sources
- https://data.transportation.gov/stories/s/FRA-Safety-Data/dakf-i7zd: “Datasets and reports currently include data through August 31, 2026.”
- https://data.transportation.gov/api/views/85tf-25kj: “Rail Equipment Accident/Incident Data (Form 54)”
- https://data.transportation.gov/api/views/m2f8-22s6: “It contains the current crossing inventory - one record for each crossing.”
- https://data.transportation.gov/api/views/85tf-25kj: “Public Domain U.S. Government”
- https://data.transportation.gov/api/views/m2f8-22s6: “Public Domain”
Information and education only. Not financial, investment, legal or tax advice. Listings can be inaccurate, incomplete or out of date and are provided "as is". Free tiers, limits and licenses belong to each provider and can change, so check the provider's own terms before you rely on them. Terms & Disclaimer