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

FileContentsSize
/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 →

Regenerated when the pipeline runs; last generated 2026-10-19. Cached at the edge for 15 minutes.

cameras.json — every field

FieldTypeMeaning
idnumber | stringA 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, lonnumberCoordinates as recorded in OSM (WGS 84).
provincestring | nullAssigned at build time by point-in-polygon against OSM administrative boundaries (ISO3166-2 areas), not a geocoding service.
sourceenumWhich 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.
categoryenumOur classification layer, not an OSM tag: police_alpr, toll, border, private. Rules are in scripts/build-cameras.mjs.
operatorstring | nullNormalized operator name (e.g. "YRP" resolves to "York Regional Police"). null means OSM records no operator — true of a large share of the data.
rawOperatorstring | nullThe original OSM value when normalization changed it, so you can see what we did.
manufacturerstring | nullNormalized vendor name from the manufacturer or brand tag.
vendorDisputedbooleantrue 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, directionstring | number | nullPassed through from OSM tags where present.
tollMethodstring | nullFrom the toll_method tag on gantries.
photostring | nullCommunity photograph URL where one exists. Currently only a handful, hosted on Wikimedia Commons.
provenanceenum"osm" — somebody mapped it. "operator" — the institution publishes it and the record is theirs. See below.
sourceIdstring?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, siteNotestring | nullThe operator's own identifier, intersection name, municipality, in-service date and note. No crowd pin carries any of these.
osmIdnumber | nullThe community node for the same camera where one exists, so an adopted record still credits the mapper who found it first.
notInOperatorListstring?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.

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}'

Returns 244 of 931 as of the current dataset. The classification rules that produce category are in build-cameras.mjs — read them before citing the number, because the classification is ours, not OpenStreetMap's.

Limitations — read before citing

Licence and attribution

Using this for a story? Tell us what you need and we will help you verify it, including the parts that weaken your angle. [email protected] · the full research base · what this site collects about you