Take the data
Everything the map draws is a static JSON file you can fetch, cite and check. No key, no signup, no rate limit, CORS enabled so it works from a browser. If you are verifying something we published, this is the fastest route.
Endpoints
| File | Contents | Size | |
|---|---|---|---|
/data/cameras.json | Every mapped camera, classified, with province and the OSM tag that put it in the dataset.1,673 cameras | 534 KB | Download → |
/data/changes.json | What appeared and disappeared between pipeline runs — the change feed behind "new this week".diff + history | 62 KB | Download → |
/data/news.json | Auto-collected ALPR news items with publication dates, outlets and a Canada flag.rolling 40 items | 28 KB | Download → |
cameras.json — every field
| Field | Type | Meaning |
|---|---|---|
id | number | string | A number is an OpenStreetMap node ID — append it to openstreetmap.org/node/ for the source record and its edit history. A string ("york-cctv-12") is a camera the operator publishes itself; sourceId says which list. |
lat, lon | number | Coordinates as recorded in OSM (WGS 84). |
province | string | null | Assigned at build time by point-in-polygon against OSM administrative boundaries (ISO3166-2 areas), not a geocoding service. |
source | enum | Which OSM tag put this node in the dataset: alpr_tagged, toll_gantry, or border_control — kept even when an operator record supersedes the node, so adopting a better source cannot quietly shrink the denominator behind the tolling finding. operator_published means OSM never had this camera at all. |
category | enum | Our classification layer, not an OSM tag: police_alpr, toll, border, private. Rules are in scripts/build-cameras.mjs. |
operator | string | null | Normalized operator name (e.g. "YRP" resolves to "York Regional Police"). null means OSM records no operator — true of a large share of the data. |
rawOperator | string | null | The original OSM value when normalization changed it, so you can see what we did. |
manufacturer | string | null | Normalized vendor name from the manufacturer or brand tag. |
vendorDisputed | boolean | true where a node is tagged as Flock Safety hardware at a police service. Flock states it holds no Canadian police contracts and the term is used generically, so we flag rather than assert. |
zone, cameraType, direction | string | number | null | Passed through from OSM tags where present. |
tollMethod | string | null | From the toll_method tag on gantries. |
photo | string | null | Community photograph URL where one exists. Currently only a handful, hosted on Wikimedia Commons. |
provenance | enum | "osm" — somebody mapped it. "operator" — the institution publishes it and the record is theirs. See below. |
sourceId | string? | Key into the top-level sources object, which carries the publisher, the portal link, the licence, and the records request that surfaced it. |
siteId, siteLabel, siteArea, siteActive, siteNote | string | null | The operator's own identifier, intersection name, municipality, in-service date and note. No crowd pin carries any of these. |
osmId | number | null | The community node for the same camera where one exists, so an adopted record still credits the mapper who found it first. |
notInOperatorList | string? | Set on a crowd pin attributed to a force whose own complete published list does not contain it. A discrepancy we show rather than resolve. |
Where a camera came from
Every camera in this file carries a provenance value, because two very
different claims sit in the same dataset and flattening them would be the dishonest move.
-
osm— somebody mapped it. A contributor stood at a corner, or looked at aerial imagery, and drew a point. That is provenance for the record, not proof of the fact: the operator may be wrong, the camera may be gone, the vendor tag may be a guess. 1,605 of our 1,673 records are these. -
operator— the institution publishes it. The force's own register of its own cameras, with its own site identifier, the intersection as it names it, and the date it says the camera went live. 68 records, and on the map they carry a white ring.
Where both exist for one camera, the operator's record takes the point and keeps the
community node as osmId — the mapper who found it first still gets the link.
Where a crowd pin names a force whose own complete published list does not contain
it, we do not delete the pin and we do not trust it: it gets
notInOperatorList, and the discrepancy goes into a records request.
9 points are in that state
right now.
York Regional Police Community Safety Data Portal — 68 cameras. The publisher's page · the raw feed we read. Found while answering York Regional Police’s clarification letter on our MFIPPA request — file 26-1898. ALPR at these sites is claimed but not confirmed camera by camera: ALPR at every location, per York Regional Police Services Board, June 25, 2025 — Report of the Chief of Police, CCTV Cameras Annual Report and Program Expansion.
Reproducing the tolling finding
The headline claim on /findings is checkable in three lines, which is
the point of publishing the source field:
curl -s https://readback.ofrecord.ca/data/cameras.json \
| jq '[.cameras[] | select(.source == "alpr_tagged")] |
{alpr_tagged: length,
toll: [.[] | select(.category == "toll")] | length}' Limitations — read before citing
- These are mapped cameras, not an inventory. Locations are crowdsourced from OpenStreetMap, which means somebody mapped them, not that anyone verified them. A camera missing from this file may well exist. Treat every count as a floor.
- 888 of 1,673 records have no operator. We cannot say who runs them, so per-operator counts are floors too.
- Newly mapped is not newly installed.
changes.jsonrecords when something entered the dataset, which is a fact about OpenStreetMap, not about deployment. - Vehicle-mounted ALPR is not in here at all. Most Canadian scanning capacity is mobile and has no fixed location. See finding 02.
-
categoryis our judgement. OpenStreetMap does not classify these; we do, by rules you can read. Reasonable people could draw the toll/police line differently, and that choice materially changes the headline number.
Licence and attribution
- Camera data from OpenStreetMap: © OpenStreetMap contributors, licensed under the Open Database Licence (ODbL) 1.0. That part of this dataset is a derivative database and is re-published under the same licence — if you build on it, share alike and attribute OpenStreetMap.
- York Regional Police Community Safety Data Portal: © 2024 York Regional Police BI. These rows are not ODbL and are not ours to relicense — York Regional Police open data terms — non-commercial use only, no warranty of accuracy or completeness. We use them non-commercially, link every row back to the publisher's own record, and pass the restriction on to you rather than flattening it into the licence above.
- Atlas of Surveillance: research in this project draws on the Electronic Frontier Foundation's Atlas of Surveillance, licensed CC BY 4.0. The raw CSV is redistributed with attribution in our repository.
- Basemap: tiles from OpenFreeMap (© OpenMapTiles, data from OpenStreetMap).
- Our classification, normalisation and research: use it freely, with credit to Readback and a link. Corrections are welcome and get logged publicly.