# Restaurant Inspection Scores & Violations (Official City Data) (`civicdataforge/restaurant-inspection-scores`) Actor

- **URL**: https://apify.com/civicdataforge/restaurant-inspection-scores.md
- **Developed by:** [Bryan](https://apify.com/civicdataforge) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Restaurant Inspection Evidence — 7 Official Jurisdictions

This Actor retrieves official restaurant and food-facility inspection records from seven government
feeds and preserves each jurisdiction's meaning. It does not translate unlike scores into a fake
national ranking.

### Verified source coverage

Live one-record canaries ran on 2026-08-02 against every source:

| Jurisdiction | Official dataset | Portal | Newest row observed | Freshness |
|---|---|---|---|---|
| New York City, NY | [43nn-pn8j](https://data.cityofnewyork.us/resource/43nn-pn8j.json) | Socrata | 2026-07-30 | current |
| Chicago, IL | [4ijn-s7e5](https://data.cityofchicago.org/resource/4ijn-s7e5.json) | Socrata | 2026-07-31 | current |
| Austin, TX | [ecmv-9xxi](https://data.austintexas.gov/resource/ecmv-9xxi.json) | Socrata | 2026-05-22 | aging |
| Cincinnati, OH | [rg6p-b3h3](https://data.cincinnati-oh.gov/resource/rg6p-b3h3.json) | Socrata | 2026-07-31 | current |
| Boulder County, CO | [tuvj-xz3m](https://data.colorado.gov/resource/tuvj-xz3m.json) | Socrata | 2025-08-29 | stale |
| Montgomery County, MD | [46p5-g5na](https://data.montgomerycountymd.gov/resource/46p5-g5na.json) | Socrata | 2024-10-03 | stale |
| King County, WA | [FeatureServer 0](https://services.arcgis.com/Ej0PsM5Aw677QF1W/arcgis/rest/services/RESTAURANT_INSPECTIONS_POINT_857/FeatureServer/0) | ArcGIS | 2024-03-30 | stale |

`current`, `aging`, and `stale` describe the newest row returned by the bounded canary. They do not
guess why a publisher has not posted newer records. This makes nominal coverage distinguishable from
currently updating coverage.

### Evidence contract

Every record includes:

- stable `record_key` and content-based `record_fingerprint`;
- published business and inspection identifiers where available;
- facility type, risk, geocode, critical flag, violation code, and violation detail where published;
- explicit `score_direction` and `source_row_grain`;
- official source URL, dataset ID, portal, attribution, fetch time, and source status; and
- the original source row in `raw`, with configured phone fields removed.

The Actor also writes `RUN-RECEIPT` to its default key-value store. The receipt contains requested
jurisdictions, effective limits and filters, per-source counts, newest observed dates, freshness,
errors, warnings, completeness, and a canonical SHA-256 `receipt_hash`.

### Input

| Field | Meaning |
|---|---|
| `cities` | Any subset of `nyc`, `chicago`, `austin`, `cincinnati`, `boulder`, `montgomery`, `king_county`. |
| `businessNameContains` | Case-insensitive establishment substring. |
| `resultContains` | Jurisdiction-published result/grade substring; scores are never converted into grades. |
| `since` / `until` | Inclusive `YYYY-MM-DD` inspection range. |
| `maxRecordsPerCity` | Newest-first bound from 1 to 5,000 per jurisdiction. |
| `socrataAppToken` | Optional caller-owned Socrata app token, kept secret and sent only as `X-App-Token`. |

### Interpretation boundaries

- NYC scores are lower-is-better; Austin scores are higher-is-better; other jurisdictions may publish
  no score or a source-specific score. Compare within a jurisdiction unless a qualified analyst defines
  a documented transformation.
- Some feeds publish one row per inspection and others one row per violation. `source_row_grain` makes
  this explicit.
- A stale feed is still factual historical data, but it is not described as current monitoring.
- A bounded query is not a claim that the Actor enumerated every matching record.

### Tests

`npm test` checks normalization, identity keys, stable fingerprints, date bounds, ArcGIS pagination,
source receipts, and receipt hashing. `npm run test:live` performs a bounded official-source pull.
`node test_sources_live.mjs` canaries all seven sources and prints their observed freshness.

# Actor input Schema

## `cities` (type: `array`):

Official inspection feeds to query. Every output and run receipt discloses source age, row grain, and source status.

## `businessNameContains` (type: `string`):

Case-insensitive establishment-name substring. Applied server-side where supported and verified client-side for every source.

## `resultContains` (type: `string`):

Case-insensitive substring on the jurisdiction's published result or grade. A source with no such field returns no matches; scores are never guessed into grades.

## `since` (type: `string`):

Inclusive ISO date YYYY-MM-DD.

## `until` (type: `string`):

Inclusive ISO date YYYY-MM-DD.

## `maxRecordsPerCity` (type: `integer`):

Bounded newest-first query limit per jurisdiction (1-5,000).

## `socrataAppToken` (type: `string`):

Optional caller-owned app token for a dedicated Socrata rate-limit pool. It is sent only as X-App-Token and never returned.

## Actor input object example

```json
{
  "cities": [
    "chicago"
  ],
  "maxRecordsPerCity": 25
}
```

# Actor output Schema

## `results` (type: `string`):

API URL for normalized inspection records.

## `runReceipt` (type: `string`):

Per-source status, counts, freshness, warnings, limits, and receipt hash.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "cities": [
        "chicago"
    ],
    "maxRecordsPerCity": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("civicdataforge/restaurant-inspection-scores").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "cities": ["chicago"],
    "maxRecordsPerCity": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("civicdataforge/restaurant-inspection-scores").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "cities": [
    "chicago"
  ],
  "maxRecordsPerCity": 25
}' |
apify call civicdataforge/restaurant-inspection-scores --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=civicdataforge/restaurant-inspection-scores",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bBZtR2jMMwiavqSBk/builds/8dxjMaSm3rG86I21F/openapi.json
