CA Food Facility Inspections - San Francisco Restaurant History
Pricing
from $0.03 / 1,000 inspection records
CA Food Facility Inspections - San Francisco Restaurant History
SF restaurant / food-facility inspection history (public data, 2016-present, ~126k records): pass / conditional / closure, violation codes + text, scores, risk. Compliance & closure diligence for franchise / restaurant buyers.
Pricing
from $0.03 / 1,000 inspection records
Rating
0.0
(0)
Developer
Wenhao Yang
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
San Francisco's Department of Public Health publishes its food-facility inspection history as open data (city Socrata, free public data). The catch: the city has published it in three successive datasets with different schemas, so a naive lookup only ever sees one slice. This actor merges all three into one queryable, charged-per-record API - the full SF restaurant inspection history from 2016 to today.
Built for: restaurant / ghost-kitchen / franchise compliance & closure diligence, supply-chain vetting, insurance, and food-safety research.
What it covers
San Francisco food-facility inspections, 2016 -> present (~126k records across three eras):
| Era | Rows | Granularity | What it records |
|---|---|---|---|
current (2024-present) | ~22k | per inspection | Pass / Conditional Pass / Closure, violation codes + code text + violation count, exact permit number, DBA, neighborhood, inspector |
y2020_2023 | ~50k | per violation | PASS / CONDITIONAL PASS / CLOSURE, violation severity (Minor / Major / OUT...), description |
y2016_2019 | ~54k | per violation | inspection score (0-100), risk category (High / Moderate / Low), violation description |
Why three eras? SF changed systems in 2016, 2020 and 2024 - the old tables froze and a new one started, with a ~2023-08 -> 2024-01 gap between eras. There is no exact key linking a business across all three, so cross-era history is matched on business name (generation: all). Within the current era, permit_number is the stable per-business key.
Note on era-specific filters: only the eras that actually record a field honor a filter on it. A
rating/closurefilter runs against the current and 2020-2023 eras only (the 2016-2019 era has no rating column - it records a score instead), so "show every closure across SF locations" returns closures from 2020 onward. Userisk/minScorefor the 2016-2019 era.
Typical questions
- "Show every Closure a restaurant chain has had across its SF locations."
- "What violations does this food facility (by permit number) have on its latest inspections?"
- "Which violations mention rodents / vermin / improper cooling - current and historical?"
- "Find high-risk (or low-score) inspections from the 2016-2019 era for this business."
- "How many Conditional Pass results did restaurants in the Mission get last year?"
Results vs. violations - row semantics
Each era has its own row granularity, and the generation field tells you which:
- current = one row per inspection (violation text is the full
violation_codesblob;violationCount= how many). - y2020_2023 / y2016_2019 = one row per violation (a clean inspection still emits one row with empty violation text).
Inputs
| Input | What it does |
|---|---|
generation | current (default) / y2020_2023 / y2016_2019 / all (full history by name) |
business | business-name substring |
permit | exact permit number (current era only - the stable store key) |
dateFrom / dateTo | inspection date window |
rating | pass / conditional / closure |
keyword | violation-text substring |
risk | High / Moderate / Low (2016-2019 era) |
severity | violation severity text (2020-2023 era) |
minScore | only inspections scoring at least this (2016-2019 era) |
aggregate / groupBy | one row per group (rating / neighborhood / inspectionType / severity / risk) with a count |
maxResults | cap records (default 50) |
Default run = the ~50 most recent SF inspections (2024-present era) - fast enough for the daily auto-test, and a live look at what SF inspectors are finding right now.
Note: a run is capped at $5 of usage - a request large enough to reach it (roughly 5,000 records at the entry price) is cut off part-way, and the truncated run still reports success. For whole-corpus counts, use aggregate.
Example inputs
Latest inspections for one restaurant - business is a case-insensitive substring; the default current era is one row per inspection.
{"business": "Zingari", "maxResults": 5}
Trace one business across all three eras - generation=all matches on business name and returns the pre-2024 rows too.
{"business": "Zingari", "generation": "all", "maxResults": 20}
Every closure across the city - rating=closure runs against the current and 2020-2023 eras.
{"rating": "closure", "maxResults": 25}
Inspections whose violation text mentions a term - keyword matches the violation text.
{"keyword": "vermin", "maxResults": 10}
Low cost
From $0.00005 per record, down to $0.00003 at Gold - billed only for the rows you use, and each record is metered individually.
Behind this is an awkward source, unified. SF has published its food-inspection history as three successive datasets with different schemas (2016-2019 carries a 0-100 score, 2020-2023 carries a Pass/Conditional/Closure rating, 2024+ is per-inspection with violation codes) - and there is no key linking a restaurant across them; even the rating enum was once mistyped by the city (CONDITIIONAL). We normalize all three onto one schema, one rating vocabulary, and one cross-era store history matched on name - with the future-dated garbage rows SF lets into its tables clamped out so a date filter can never surface a 2031 inspection. You query one clean history; the schema archaeology stays on our side.
Example output
One inspection - business=Zingari on the default current era returns ZINGARI RISTORANTE's rows (permit is the exact per-business key); one of them:
{"platform": "ca-food-safety","source": "sf-food-current","city": "San Francisco","generation": "2024-present","mode": "rows","date": "2026-09-15","year": "2026","inspectionType": "","rating": "Pass","score": "","severity": "","riskCategory": "","violationText": "113996, 113998, 114037, 114429, 114429.3, 114429.5 - Keep potentially hazardous foods (PHF) cold at 41F or below or hot held at 135F or above. Immediately discontinue storing PHF at room temperature., 114130-114130.5, 114132, 114133, 114137, 114139, 114153, 114163, 114165, 114167, 114169, 114175, 114177, 114180, 114182 - Ensure all equipment is approved, properly installed, clean, and maintained in good repair. Ensure all appliances are NSF-approved, commercial grade, durable, and easily cleanable., 114259, 114259.1, 114259.4, 114259.5 - Eliminate the infestation/activity of cockroaches/rodents/flies/vermin from the food facility by using only approved methods. Remove all evidence of the infestation and thoroughly clean and sanitize all affected surfaces. Construct, equip, maintain and operate the food facility so as to prevent the entrance and harborage of animals, birds and vermin including, but not limited to, rodents and insects., 114123, 114197, 114328(o) - Eliminate sewage backflow into the facility. Clean and sanitize all areas contaminated with sewage with a bleach solution (1 cup bleach per 9 cups water).Hire a licensed plumbing contractor if necessary. All contaminated food items must be discarded. All items that cannot be properly sanitized must be discarded., 114143(d), 114266, 114268, 114268.1, 114271, 114272 - Provide walls / ceilings using materials that are durable, smooth, nonabsorbent, light-colored, and washable surfaces. All floor surfaces, other than the customer service areas, shall be approved, smooth, durable, and made of nonabsorbent material that is easily cleanable. Approved base coving shall be provided in all areas, except customer service areas and where food is stored in original unopened containers. Food facilities shall be fully enclosed. All food facilities shall be kept clean and in good repair., 113967, 113976, 113980, 113988, 113990, 114035, 114254.3, 113975 - Discard all contaminated/adulterated food immediately if it bears or contains any poisonous or deleterious substance that may render it impure or injurious to health., - Food, equipment, or utensils that are found to be unsanitary or in disrepair may be Voluntarily Condemned and Destroyed by the person in charge.","violationCount": "7","businessName": "ZINGARI RISTORANTE","permitNumber": "29047","businessId": "","address": "501 POST ST","postalCode": "","neighborhood": "Tenderloin","district": "2","inspector": "John Wells","latitude": "37.78791300000100","longitude": "-122.4103950000020","groupKey": "","groupCount": ""}
Source
- SF Health Inspections 2024-Present - official.
- SF Restaurant Scores 2020-2023 - official.
- SF Restaurant Scores 2016-2019 - official.
Note: inspection results are SF's own public health ratings. A "Closure" result means the facility was closed at the time of that inspection; reasons are recorded in free-text violation notes rather than a structured field.