publicdataau publicdata.au on GitHub
Published by Transport for NSW under CC BY 3.0 AU and republished here without change to the content. Transport for NSW has not endorsed this site.An independent republication of open government data. No government agency has endorsed it. Read more

Road crashes, New South Wales

live
Publisher Transport for NSWUpdated yearlyLicence CC BY 3.0 AULatest 2025-10-10Rows 92,189Fields 62

NSW Crash Data from Transport for NSW, one row per crash for the latest five reporting years. Each crash has its degree, year, month, day of week and two-hour band, street, town, council area and coordinates, the road and lighting conditions, the road user movement and definitions for crash type codes, the vehicles involved and the number of people killed and injured by severity.

Also called: NSW Crash Data, NSW road toll and crash statistics, Transport for NSW road crash data by crash, NSW car accident statistics.

Before you use it
Which crashes are included?
The crashes reported to NSW Police on a public road in the five reporting years of the release, in which a person was killed or injured or a vehicle was towed away. Each row is one crash, with its location, road and conditions and the number of people killed or injured.
Why does each version cover only five years?
Transport for NSW publishes a rolling five years each October and adds the release as a new file. This entry follows the newest file, so each version is one release. Earlier releases stay here as earlier versions.
Can I count the road toll from this?
The killed column counts people who died within 30 days of the crash, as the publisher reports them. Add it across the crashes of a year to get the deaths the publisher counted for that year.
92,184 crashes drawn in 5,561 cells of 0.05 degrees, the fullest with 2,019.
Crashes counted in cells of 0.05 degrees. State outlines from the ABS Australian Statistical Geography Standard 2021, CC BY 4.0.
92,189crashes
2020 to 2024years drawn
62fields
12formats
1version
05k10k15k20k2020 Fatal: 2642020 Injury: 12,5722020 Non-casualty (towaway): 5,86820202021 Fatal: 2602021 Injury: 11,4472021 Non-casualty (towaway): 5,81020212022 Fatal: 2632022 Injury: 11,7002022 Non-casualty (towaway): 6,28220222023 Fatal: 3032023 Injury: 12,6562023 Non-casualty (towaway): 5,74720232024 Fatal: 2982024 Injury: 12,8792024 Non-casualty (towaway): 5,8402024
FatalInjuryNon-casualty (towaway)
Crashes per year by degree of crash, 2020 to 2024. Both figures are counts of rows from version 2025-10-10, worked out in the build. Nothing else is added.

Made for agents

Connect your AI agent

Any agent that connects to publicdata.au/mcp can find this dataset, read its 62 fields, count and filter across all 92,189 rows and diff its versions. Every answer names the version and carries TfNSW's attribution. No key.

Then ask it: What does Road crashes, New South Wales hold, and what changed in the newest version?

claude mcp add --transport http publicdata https://publicdata.au/mcp

One command. No key, no account, no sign-up.

Download it as Excel, CSV, JSON and 9 more formats

Pick a format and a version. Excel is picked first because it opens in the tools most offices have. The URL is yours to keep. A dated version never changes.

Format
"Latest" redirects to the newest version and will change when the publisher releases again. A dated version never changes.
https://publicdata.au/d/nsw-road-crashes/latest/data.xlsx
Download

In your own tools

Use it in Excel, R, Python and more

Excel and Power BI read the CSV from its address and refresh from it. The R and Python packages take any dataset on this site by its slug, so a new dataset needs no new release. The DuckDB file attaches read-only over HTTPS, and a query reads only the blocks it touches.

The dated URL in the code never changes. https://publicdata.au/d/nsw-road-crashes/latest/ redirects to the newest version.

https://publicdata.au/d/nsw-road-crashes/latest/data.csv

In Excel choose Data, then From Web, and paste this address. Excel keeps it, so Refresh All reads the newest version. A sheet holds about a million rows; past that, load the query to the Data Model.

What is in it

Column names are made snake_case and the publisher's original header is kept beside each one. Blank cells are null. Nothing is added, removed, ranked or summarised.

FieldTypePublisher's headerNote
crash_idintegerCrash ID
degree_of_crashstringDegree of crash
degree_of_crash_detailedstringDegree of crash - detailed
reporting_yearintegerReporting year
year_of_crashintegerYear of crash
month_of_crashstringMonth of crash
day_of_week_of_crashstringDay of week of crash
two_hour_intervalsstringTwo-hour intervals
street_of_crashstringStreet of crash
street_typestringStreet type
distanceintegerDistance
directionstringDirection
identifying_featurestringIdentifying feature
identifying_feature_typestringIdentifying feature type
townstringTown
route_nointegerRoute no.
school_zone_locationstringSchool zone location
school_zone_activestringSchool zone active
type_of_locationstringType of location
latitudenumberLatitudeAs published. The publisher's data manual does not state the datum.
longitudenumberLongitudeAs published. The publisher's data manual does not state the datum.
lgastringLGA
urbanisationstringUrbanisation
conurbation_1stringConurbation 1
alignmentstringAlignment
primary_permanent_featurestringPrimary permanent feature
primary_temporary_featurestringPrimary temporary feature
primary_hazardous_featurestringPrimary hazardous feature
street_lightingstringStreet lighting
road_surfacestringRoad surface
surface_conditionstringSurface condition
weatherstringWeather
natural_lightingstringNatural lighting
signals_operationstringSignals operation
other_traffic_controlstringOther traffic control
speed_limitstringSpeed limit
road_classification_adminstringRoad classification (admin)
rum_codeintegerRUM - code
rum_descriptionstringRUM - description
dca_codeintegerDCA - code
dca_descriptionstringDCA - description
dca_supplementstringDCA supplement
first_impact_typestringFirst impact type
key_tu_typestringKey TU type
other_tu_typestringOther TU type
traffic_unitsintegerNo. of traffic units involved
killedintegerNo. killed
seriously_injuredintegerNo. seriously injured
moderately_injuredintegerNo. moderately injured
minor_other_injuredintegerNo. minor-other injured
sa2_2021_codestring(spine: sa2)Code of the Statistical Area Level 2 (2021) the point falls in. Joined by location from abs-sa2-2021, not published by the publisher.
sa2_2021_namestring(spine: sa2)Name of the Statistical Area Level 2 (2021) the point falls in. Joined by location from abs-sa2-2021, not published by the publisher.
lga_2025_codestring(spine: lga)Code of the Local Government Area (2025) the point falls in. Joined by location from abs-lga-2025, not published by the publisher.
lga_2025_namestring(spine: lga)Name of the Local Government Area (2025) the point falls in. Joined by location from abs-lga-2025, not published by the publisher.
sal_2021_codestring(spine: suburb)Code of the Suburb and Locality (2021) the point falls in. Joined by location from abs-suburbs-localities-2021, not published by the publisher.
sal_2021_namestring(spine: suburb)Name of the Suburb and Locality (2021) the point falls in. Joined by location from abs-suburbs-localities-2021, not published by the publisher.
poa_2021_codestring(spine: postcode)Code of the Postal Area (2021) the point falls in. Joined by location from abs-postal-areas-2021, not published by the publisher.
poa_2021_namestring(spine: postcode)Name of the Postal Area (2021) the point falls in. Joined by location from abs-postal-areas-2021, not published by the publisher.
sed_2025_codestring(spine: state_electorate)Code of the State Electoral Division (2025) the point falls in. Joined by location from abs-state-electoral-divisions-2025, not published by the publisher.
sed_2025_namestring(spine: state_electorate)Name of the State Electoral Division (2025) the point falls in. Joined by location from abs-state-electoral-divisions-2025, not published by the publisher.
ced_2025_codestring(spine: federal_electorate)Code of the Commonwealth Electoral Division (2025) the point falls in. Joined by location from abs-federal-electoral-divisions-2025, not published by the publisher.
ced_2025_namestring(spine: federal_electorate)Name of the Commonwealth Electoral Division (2025) the point falls in. Joined by location from abs-federal-electoral-divisions-2025, not published by the publisher.

Download this table as a data dictionary (Excel), or read it as a Frictionless Table Schema at schema.json. The key is crash_id.

A sample of 10 rows

From the latest version, newest first by reporting year, each degree of crash in turn, then in the publisher's order, with every field. A blank cell is shown as null.

crash_iddegree_of_crashdegree_of_crash_detailedreporting_yearyear_of_crashmonth_of_crashday_of_week_of_crashtwo_hour_intervalsstreet_of_crashstreet_typedistancedirectionidentifying_featureidentifying_feature_typetownroute_noschool_zone_locationschool_zone_activetype_of_locationlatitudelongitudelgaurbanisationconurbation_1alignmentprimary_permanent_featureprimary_temporary_featureprimary_hazardous_featurestreet_lightingroad_surfacesurface_conditionweathernatural_lightingsignals_operationother_traffic_controlspeed_limitroad_classification_adminrum_coderum_descriptiondca_codedca_descriptiondca_supplementfirst_impact_typekey_tu_typeother_tu_typetraffic_unitskilledseriously_injuredmoderately_injuredminor_other_injuredsa2_2021_codesa2_2021_namelga_2025_codelga_2025_namesal_2021_codesal_2021_namepoa_2021_codepoa_2021_namesed_2025_codesed_2025_nameced_2025_codeced_2025_name
1339151FatalFatal20242024JanuaryMonday08:00 - 09:59APPINRD650NorthSOUTHERN EXPRESSWAYOPCATARACT177NoNot a school zone2-way undivided-34.297807150.90541WollongongWollongong met. areaSyd-Newc-Woll Gtr conurbationCurvedEmbankment/cuttingnullnullOffSealedWetRainingDaylightNilNo traffic controls80 km/hState81Off left/rt bnd=>obj803Off right bend into objLeftVehicle - ObjectCar (sedan/hatch)null11000107021135Illawarra Catchment Reserve18450Wollongong10853Cataract2560256010034Heathcote111Cunningham
1340248InjuryModerate Injury20242023DecemberThursday12:00 - 13:59SYD EINFELDDR15NorthOLD SOUTH HEADRDBONDI JUNCTION172NoNot a school zoneDivided road-33.890904151.253302WaverleySydney metro. areaSyd-Newc-Woll Gtr conurbationCurvednullnullnullUnknown / not statedSealedWetRainingDaylightNilNo traffic controls50 km/hState30Rear end301Same - Rear endnullRear endCar (sedan/hatch)Car (sedan/hatch)20010118011341Bondi Junction - Waverly18050Waverley10465Bondi Junction2022202210021Coogee144Wentworth
1340242Non-casualty (towaway)Non-casualty (towaway)20242024JanuaryMonday12:00 - 13:59FORESTRD300SouthMT CARLTRLGOONOO FOREST7519NoNot a school zone2-way undivided-31.928465149.012275Dubbo RegionalCountry non-urbanRest of NSW - RuralStraightnullnullnullUnknown / not statedSealedDryFineDaylightNilNo traffic controls100 km/hRegional70Off road to left701Off carriageway to leftnullRollover4 wheel drive / SUVnull10000105031103Dubbo Surrounds12390Dubbo11719Goonoo Forest2830283010026Dubbo133Parkes
1339984FatalFatal20242024JanuaryWednesday14:00 - 15:59CASTLEREAGHHWY3000NorthBERIDARDCURBAN18NoNot a school zone2-way undivided-31.525981148.556366GilgandraCountry non-urbanRest of NSW - RuralCurvednullnullnullNilSealedDryFineDaylightNilNo traffic controls110 km/hState20Head on201Opp - Head onnullHead-onLight truck utility(from 2018)4 wheel drive / SUV21021105031104Gilgandra12950Gilgandra11167Curban2827282710007Barwon133Parkes
1340261InjuryModerate Injury20242024JanuaryMonday16:00 - 17:59BEAUCHAMPRD10EastPERONNEWAYMATRAVILLE7340NoNot a school zoneT-junction-33.953048151.23971RandwickSydney metro. areaSyd-Newc-Woll Gtr conurbationStraightnullnullnullNilSealedDryFineDaylightNilNo traffic controls50 km/hRegional71Off rd left => obj703Left off cway into objectnullOther angleCar (sedan/hatch)Light truck30010118021653Matraville - Chifley16550Randwick12534Matraville2036203610051Maroubra122Kingsford Smith
1340260Non-casualty (towaway)Non-casualty (towaway)20242024JanuaryMonday18:00 - 19:59THE RAMPARTMS0Right on the spotNUMBER 7HNUMINA BEACHnullNoNot a school zone2-way undivided-33.516059151.300576Central CoastCountry urbanSyd-Newc-Woll Gtr conurbationCurvedSteep gradenullnullUnknown / not statedSealedDryOvercastDuskNilNo traffic controls50 km/hLocal83Off rt/rt bnd=>obj803Off right bend into objRightVehicle - ObjectCar (sedan/hatch)null10000102011040Umina - Booker Bay - Patonga11650Central Coast (NSW)14025Umina Beach2257225710030Gosford139Robertson
1339986FatalFatal20242024JanuaryThursday16:00 - 17:59GWYDIRHWY0Right on the spotGREENSLANESWAN CREEK12NoNot a school zoneX-intersection-29.668729152.981533Clarence ValleyCountry non-urbanRest of NSW - RuralStraightnullnullnullNilSealedDryFineDuskNilNo traffic controls100 km/hState40U turn304Same - U-turnnullOther angleCar (sedan/hatch)B-double (road train prior 98)21020104011081Grafton Surrounds11730Clarence Valley13721Swan Creek (NSW)2462246210019Clarence132Page
1340263InjurySerious Injury20242024JanuaryWednesday16:00 - 17:59PACIFICHWY5300SouthFRASERRDCOWAN10NoNot a school zone2-way undivided-33.559577151.191614HornsbySydney metro. areaSyd-Newc-Woll Gtr conurbationCurvednullnullnullUnknown / not statedSealedWetOvercastDaylightNilNo traffic controls80 km/hState81Off left/rt bnd=>obj803Off right bend into objLeftVehicle - ObjectMotorcyclenull10100121021404Berowra - Brooklyn - Cowan14000Hornsby11097Cowan2081208110037Hornsby104Berowra
1340270Non-casualty (towaway)Non-casualty (towaway)20242024JanuaryTuesday20:00 - 21:59CORRIMALST0Right on the spotNUMBER 121-125HNWOLLONGONG581NoNot a school zone2-way undivided-34.425289150.899916WollongongWollongong met. areaSyd-Newc-Woll Gtr conurbationStraightnullnullnullUnknown / not statedSealedDryFineDarknessNilNo traffic controls60 km/hState39Other same direction300Same - othernullOther angle4 wheel drive / SUV4 wheel drive / SUV20000107041548Wollongong - East18450Wollongong14376Wollongong2500250010092Wollongong111Cunningham
1339987FatalFatal20242024JanuaryFriday16:00 - 17:59LAKERD20NorthPACIFICSTWOOLGOOLGA4007NoNot a school zone2-way undivided-30.108237153.199993Coffs HarbourCountry urbanRest of NSW - UrbanStraightnullnullnullNilSealedWetOvercastDaylightNilNo traffic controls50 km/hRegional73Off rd rght => obj704Right off cway into objnullVehicle - Object4 wheel drive / SUVnull11100104021091Woolgoolga - Arrawarra11800Coffs Harbour14420Woolgoolga2456245610020Coffs Harbour132Page
The first row as JSON

As it appears in data.json.

GET https://publicdata.au/d/nsw-road-crashes/latest/data.json
{
  "crash_id": 1220987,
  "degree_of_crash": "Fatal",
  "degree_of_crash_detailed": "Fatal",
  "reporting_year": 2020,
  "year_of_crash": 2020,
  "month_of_crash": "January",
  "day_of_week_of_crash": "Friday",
  "two_hour_intervals": "22:00 - Midnight",
  "street_of_crash": "HUME",
  "street_type": "HWY",
  "distance": 630,
  "direction": "North",
  "identifying_feature": "COOININEE",
  "identifying_feature_type": "RD",
  "town": "COOLAC",
  "route_no": 2,
  "school_zone_location": "No",
  "school_zone_active": "Not a school zone",
  "type_of_location": "Divided road",
  "latitude": -34.858896,
  "longitude": 148.286952,
  "lga": "Cootamundra-Gundagai",
  "urbanisation": "Country non-urban",
  "conurbation_1": "Rest of NSW - Rural",
  "alignment": "Straight",
  "primary_permanent_feature": null,
  "primary_temporary_feature": null,
  "primary_hazardous_feature": null,
  "street_lighting": "Nil",
  "road_surface": "Sealed",
  "surface_condition": "Dry",
  "weather": "Fine",
  "natural_lighting": "Darkness",
  "signals_operation": "Nil",
  "other_traffic_control": "No traffic controls",
  "speed_limit": "110 km/h",
  "road_classification_admin": "State",
  "rum_code": 71,
  "rum_description": "Off rd left => obj",
  "dca_code": 703,
  "dca_description": "Left off cway into object",
  "dca_supplement": null,
  "first_impact_type": "Vehicle - Object",
  "key_tu_type": "Semi-trailer",
  "other_tu_type": null,
  "traffic_units": 1,
  "killed": 1,
  "seriously_injured": 0,
  "moderately_injured": 0,
  "minor_other_injured": 0,
  "sa2_2021_code": "113031264",
  "sa2_2021_name": "Gundagai",
  "lga_2025_code": "12160",
  "lga_2025_name": "Cootamundra-Gundagai",
  "sal_2021_code": "11022",
  "sal_2021_name": "Coolac",
  "poa_2021_code": "2727",
  "poa_2021_name": "2727",
  "sed_2025_code": "10022",
  "sed_2025_name": "Cootamundra",
  "ced_2025_code": "138",
  "ced_2025_name": "Riverina"
}

Query it without downloading

The query API returns only the rows you ask for, as JSON, NDJSON or CSV, from the same typed rows as the files. It needs no key. Build a query here and run it, then copy the URL or the code into your own work.

Try rows or aggregate for this dataset. The query builder needs JavaScript.

How filters work

Each filter is field=operator.value in the query string, and every filter must match. A number or date field compares as a number or date, and a text field compares as text. Values are case-sensitive except with ilike. Prefix not. to negate a filter, as not.eq.value.

OperatorWhat it matches
eq.valueEqual to the value.
neq.valueNot equal to the value. A blank cell does not match.
gt.valueGreater than the value.
gte.valueGreater than or equal to the value.
lt.valueLess than the value.
lte.valueLess than or equal to the value.
like.*text*Matches a pattern where * stands for any run of characters. Case-sensitive.
ilike.*text*The same as like, ignoring case.
in.(a,b,c)Equal to any value in the list. A value cannot contain a comma.
is.nullBlank in the source, or suppressed by the publisher.
ParameterWhat it does
selectFields to return, comma-separated. Every field when absent.
orderfield.asc or field.desc, comma-separated. The publisher's row order when absent.
limitRows per page, 1 to 10,000. 100 when absent.
offsetRows to skip. The next URL in each answer sets it for you.
groupOn aggregate, fields to group by, comma-separated.
metricOn aggregate, count, sum.field, avg.field, min.field or max.field, comma-separated. count when absent.
formatjson, ndjson or csv. JSON carries the provenance header, and the others carry it in response headers.

Without a version the API answers from the newest loaded version, and that answer changes when the publisher releases again. Put versions/<date>/ before rows or aggregate for an answer that never changes. /api/v1/datasets/<slug>/versions lists the loaded versions. The 1 newest version is loaded; versions lists them.

The API allows 60 requests in 10 seconds from one address. Above that it answers 429 for 10 seconds with a Retry-After header, a RateLimit-Policy header and a JSON body that gives the limit. Every API answer carries the same RateLimit-Policy. A client should wait the Retry-After seconds, or read the files, which have no limit. openapi.json describes this dataset's query paths for client generators and agents.

https://publicdata.au/mcp is a remote MCP server over Streamable HTTP with the same tools, defined in the same place, so a tool added to the pages is added here too. It needs no key and no account. The row tools are held to the query API's limit of 60 queries in 10 seconds from one address, and each call is two queries because it also counts the matching rows. Add it to Claude Code with claude mcp add --transport http publicdata https://publicdata.au/mcp, add the URL in Claude as a custom connector, or give it to any client that connects to remote MCP servers. Each queryable dataset is also a resource at https://publicdata.au/d/<slug>/fields.json, which lists its fields with their types, the publisher's descriptions, their ranges and the values they hold, so an agent can read a dataset's shape before it writes a query.

Smaller files

The same rows split by a field, one JSON file each with a GeoJSON beside it. Each file carries the same provenance header.

By year_of_crash (6 files)

by/year_of_crash/index.json lists every file with its row count.

What changed

One version for every release the publisher has made since this site started following the dataset. The date is the day the file changed on the portal.

versions.json · changes.json · history.tar.zst (4.2 MB, every version's Parquet and manifest)

Questions

How do I download Road crashes as a CSV file?

Open https://publicdata.au/d/nsw-road-crashes/latest/data.csv. It redirects to the newest dated version, which is https://publicdata.au/d/nsw-road-crashes/v/2025-10-10/data.csv today. The same path serves Excel, JSON, GeoJSON, Parquet, SQLite, DuckDB, GeoPackage, GeoParquet, NDJSON, Arrow. A dated URL never changes, so use it when the file must stay the same.

Can I open Road crashes in Excel?

Yes. https://publicdata.au/d/nsw-road-crashes/v/2025-10-10/data.xlsx is a workbook with the 92,189 rows on a records sheet, the field list on a second sheet and the provenance on a third. The CSV also opens in Excel. https://publicdata.au/d/nsw-road-crashes/v/2025-10-10/data.csv.gz is the CSV at about a tenth of the size.

What years does Road crashes cover?

The current version covers 2020 to 2024. Each release from TfNSW becomes a new dated version here, and earlier versions stay online.

How often is Road crashes updated?

TfNSW releases it yearly. This site checks the portal every week and adds a dated version when the file changes.

Can I use Road crashes commercially?

Yes. CC BY 3.0 AU allows commercial use, redistribution and derived works as long as the attribution is kept. The attribution string is in this page's side column and inside every file.

Is this the official source for Road crashes?

No. The publisher is Transport for NSW, and its page is https://data.nsw.gov.au/data/dataset/2-nsw-crash-data. This site republishes the publisher's file without changing its content. The original sits beside every version as source.xlsx with its SHA-256, so the two can be compared.

How do I get only the rows for one year of crash?

Every version has one JSON file per value of year_of_crash, 6 files in the current version, listed with row counts at https://publicdata.au/d/nsw-road-crashes/v/2025-10-10/by/year_of_crash/index.json. For example https://publicdata.au/d/nsw-road-crashes/v/2025-10-10/by/year_of_crash/2024.json holds the 18,939 rows where year_of_crash is 2024. A GeoJSON file sits beside each one.

What coordinate system does Road crashes use?

Latitude and longitude in decimal degrees as published. The publisher's data manual does not state the datum; GDA94 is the NSW Government's standard and differs from GDA2020 and WGS84 by under 2 metres. The GeoJSON file uses the same coordinates, which is what GeoJSON expects.

Which SA2, council area, suburb, postcode, state electorate and federal electorate is each row of Road crashes in?

Each row with coordinates carries the SA2 (2021), Council area (LGA 2025), Suburb or locality (2021), Postcode (postal area 2021), State electorate (2025) and Federal electorate (2025) its point falls in, with the code of each. This site joins them by location against the ABS boundaries, https://publicdata.au/d/abs-sa2-2021/, https://publicdata.au/d/abs-lga-2025/, https://publicdata.au/d/abs-suburbs-localities-2021/, https://publicdata.au/d/abs-postal-areas-2021/, https://publicdata.au/d/abs-state-electoral-divisions-2025/, https://publicdata.au/d/abs-federal-electoral-divisions-2025/, and TfNSW did not publish them. The schema marks each one as joined and names the boundary version. A row without coordinates, or a point outside every area, has them blank. Place columns from Australian Statistical Geography Standard (ASGS) Edition 3 boundaries, Australian Bureau of Statistics, licensed under CC BY 4.0.

What this site did to the data. Cells were typed, headers were renamed and the encoding was made UTF-8. Rows were left alone. The publisher's file sits beside every version as source.xlsx so the change can be checked.