Open Nshipyard · Toronto data
Which chains fail food-safety inspections most often.
Toronto Public Health inspects every food premise in the city and posts the result on the door: green for pass, yellow for conditional pass, red for closed. This project groups 32,421 inspections from October 2025 to October 2026 into 84 chains, normalizes for inspection frequency, and ranks each chain by its conditional-pass rate.
84
restaurant and food chains ranked, each with 10 or more Toronto locations inspected in the past year
32,421
Toronto Public Health inspections, October 2025 to October 2026, grouped from 120,879 infraction rows
6.7%
of all city inspections ended in a conditional pass; the worst chain hit 19.4%
19.4%
conditional-pass rate at the worst chain (bb.q Chicken), nearly triple the citywide average
Ranking
84 chains, ranked by conditional-pass rate.
The conditional-pass rate divides inspections that ended in a conditional pass by total inspections. Chains inspected more often (high-risk premises get up to 3 inspections a year) are not punished for it: the rate neutralizes inspection frequency. Click any row to see that chain's locations and their latest results.
Showing 0 of 0
| # | Chain | Locations | Inspections | Conditional pass | Crucial infractions | Closed |
|---|
No chains match.
Rates are per inspection.
Honest limits
What this does not show.
- 1
A conditional pass means a significant-risk infraction was found and corrected on re-inspection within 48 hours. It is not an ongoing hazard.
- 2
Rates are per inspection, not per location, because high-risk premises are inspected up to 3 times a year while low-risk ones get 1. Raw counts would punish the chains that are inspected most.
- 3
The source data does not distinguish franchised locations from corporate-owned ones.
- 4
DineSafe refreshes daily. This snapshot covers 2025-10-07 to 2026-10-07 and was pulled on 2026-10-09.
Methodology
How the chain file was built, and where it is weak.
01
Source: the City of Toronto Open Data DineSafe file, retrieved 2026-10-09: 120,879 rows, one row per inspection/infraction line, under the Open Government Licence - Toronto. Dataset page: https://open.toronto.ca/dataset/dinesafe/.
02
Inspections were built by grouping rows on (establishment id, inspection date): 81,002 inspections in total, 32,421 inside the 12-month window 2025-10-07 to 2026-10-07. An inspection's status is the worst status among its rows; its severity flags are the union of its rows.
03
Chain identity resolution is deterministic and documented: names are uppercased, punctuation stripped, legal suffixes (Inc, Ltd, Corp) and store/location numbers removed, then matched against a reviewed anchor list. 84 canonical chains, each with 10 or more locations in the window, survived the cutoff. Dual-brand premises (KFC/Taco Bell combos) are kept as their own chain, not assigned to either brand.
04
The ranking metric is conditional passes divided by inspections in the 12-month window. Inspection-frequency bias is normalized by using rates: a chain inspected 3 times a year per location can only beat or lose on its pass share, not on its inspection count.
05
The full match table (every raw name merged into each chain, with row counts) is published as CSV so franchisees and journalists can audit every merge. Re-running scripts/build_data.py against a fresh DineSafe download reproduces the tables.
06
Weaknesses: corporate-owned vs franchised is not distinguished in the source; status wording is the source's own; a few co-branded campus and gas-station premises are attributed to the premise operator rather than the food brand; addresses are published as-is with no geocoding corrections.
Data and API
Take the data with you.
The ranked chain table, the name-match table, and the per-chain locations are published as CSV and JSON. A REST API and an MCP server expose the same data for agents.
chains.csv
The ranked chain table: locations, inspections, conditional-pass, crucial, closed rates.
chains.json
Same table as JSON.
match_table.csv
Every raw establishment name merged into each chain, with row counts.
summary.json
Snapshot metadata: window, vintage, citywide baselines.
REST API
JSON endpoints, no key required.
/api/v1/summarySnapshot metadata and citywide baselines./api/v1/chainsThe full ranked chain table./api/v1/chain?id=TIM%20HORTONSOne chain: stats, name variants, and locations with latest statuses./api/openapi.jsonOpenAPI 3.1 document for the API.MCP server
POST JSON-RPC 2.0 to /mcp. Tools: chain_search, chain_lookup, ranking_summary.
curl -X POST https://dinesafe.canada.nshipyard.com/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'