# UK Food Hygiene Rating Monitor (FSA) (`inhabitable_jingle_clk/fsa-hygiene-monitor`) Actor

UK restaurant hygiene checker and food hygiene monitoring via the UK Food Hygiene Ratings API and Food Standards Agency API (FHRS data). No key.

- **URL**: https://apify.com/inhabitable_jingle_clk/fsa-hygiene-monitor.md
- **Developed by:** [James Marshall](https://apify.com/inhabitable_jingle_clk) (community)
- **Categories:** Automation, Lead generation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## UK Food Hygiene Rating Monitor (FSA)

A UK restaurant hygiene checker with built-in food hygiene monitoring. Search official UK food hygiene ratings and get alerted when they change. Built for food-safety consultants, suppliers, delivery platforms, insurers, journalists and anyone who needs to watch restaurants, takeaways, cafés, pubs, shops, schools and care homes across England, Wales, Northern Ireland and Scotland.

The records come from the official UK Food Hygiene Ratings API — the public Food Standards Agency API that publishes FHRS data for England, Wales and Northern Ireland, and FHIS data for Scotland (`https://api.ratings.food.gov.uk`, header `x-api-version: 2`). No API key, no browser, no proxies and no scraping of web pages.

**What makes this Actor different:** most FSA Actors on the Store are one-off search tools. This one keeps a snapshot under a `monitorKey`. Schedule the same input weekly (or daily) with `onlyChanges: true` and you only pay for businesses that are new, re-rated or removed.

### What you can do with it

- **Lead generation.** Find takeaways and restaurants rated 0–2 in a council or postcode district. Those businesses have been told to improve and are actively looking for help (consultants, pest control, training, cleaning, EPOS).
- **Food hygiene monitoring.** Watch a postcode, a council or a chain and get only the new openings, rating drops, rating improvements and disappeared listings since the last run.
- **Due diligence.** Check the current rating and inspection date for a supplier list, a franchise estate or an acquisition target.
- **Local reporting.** Export a clean spreadsheet of every food business in an area, with the official FSA page link on every row.

### Input

Use any mix of filters. You need at least one of: business name, postcode, council or business type.

| Field | What it does |
| --- | --- |
| Business name | Partial match on the trading name, e.g. `Greggs` or `Pizza`. |
| Postcode / address | Full or partial, e.g. `LS1 4AP` or `LS1`. |
| Council (name or ID) | As the FSA lists it: `Leeds`, `Westminster`, `Cardiff`, or the numeric LocalAuthorityId (`397`). Names are looked up live. Ambiguous names fail with the matching options. |
| Business type (name or ID) | e.g. `Takeaway/sandwich shop`, `Takeaway` (unique partial match) or `7844`. |
| Minimum / maximum rating | 0–5. Useful for "only 0–2 rated takeaways in Leeds". Non-numeric ratings (Scottish `Pass`, `Exempt`, `Awaiting Inspection`) are excluded when a rating filter is set. |
| Max results | Hard cap (default 500). You are never charged for more than this. |
| Monitor key | Name of the stored snapshot. Runs that share a key are compared. |
| Output only changed/new | If true, only output `new`, `changed` and `removed` businesses after the first (baseline) run. |

#### Example: low-rated takeaways in Leeds, then only the changes

```json
{
  "localAuthority": "Leeds",
  "businessType": "Takeaway/sandwich shop",
  "minRating": 0,
  "maxRating": 2,
  "maxResults": 500,
  "monitorKey": "leeds-low-takeaways",
  "onlyChanges": true
}
```

#### Example: one postcode district

```json
{
  "postcode": "LS1",
  "maxResults": 500,
  "monitorKey": "ls1-all",
  "onlyChanges": false
}
```

### Output

One dataset row per establishment, ready for CSV, Excel or JSON, or for Zapier, Make or n8n.

```json
{
  "fhrsId": 123456,
  "businessName": "Example Kebab House",
  "businessType": "Takeaway/sandwich shop",
  "addressLine1": "1 Example Street",
  "town": "Leeds",
  "postcode": "LS1 4AP",
  "localAuthority": "Leeds",
  "scheme": "FHRS",
  "rating": "2",
  "ratingNumeric": 2,
  "ratingDate": "2026-09-14",
  "newRatingPending": false,
  "latitude": 53.7997,
  "longitude": -1.5492,
  "sourceUrl": "https://ratings.food.gov.uk/business/123456",
  "changeType": "changed",
  "previousRating": "4",
  "previousRatingDate": "2024-03-02"
}
```

`changeType` values: `baseline` (first run), `unchanged`, `new`, `changed`, `removed`.

A `SUMMARY` record in the key-value store gives totals and counts per change type.

Phone numbers, emails and inspection score breakdowns are deliberately left out. Some businesses are sole traders trading under their own names; use the data only for food-hygiene purposes and respect UK GDPR.

### Monitoring

Each `monitorKey` keeps a snapshot in the named key-value store `fsa-hygiene-monitor-state-v2` in your own Apify account (created automatically on your first run; the Actor keeps Limited permissions). Schedule the same input (for example weekly) with `onlyChanges: true` to get only new, re-rated or removed businesses.

Removal detection is skipped, with a warning, when results were cut off by `maxResults`, so truncation is never reported as a removal. Raise `maxResults` if you need complete removal detection for a large council.

Network errors, HTTP 429 and 5xx are retried up to 4 times with backoff (1s, 2s, 4s, 8s + jitter). Other 4xx errors fail immediately.

### Pricing

Pay per result: **$1.00 per 1,000 establishments** ($0.001 per row), plus Apify's minimum actor-start event ($0.00005). You are charged only for rows delivered. Platform compute is included in the event price.

A 50-result postcode search costs about 5 cents. A 500-business weekly monitor that returns 8 changes costs a fraction of a cent if `onlyChanges` is on (you pay for the 8 change rows, not the 500).

### Good to know

- Ratings show the hygiene standard at the date of inspection, not food quality. Always check `ratingDate` and `newRatingPending`.
- England, Wales and Northern Ireland use 0–5 (FHRS). Scotland uses Pass / Improvement Required (FHIS).
- Coverage is whatever the FSA publishes (local authorities update after inspections).
- For a full nightly dump of every authority, use the FSA open-data files rather than querying the live API repeatedly.

### Related tools

Other UK open-data tools from the same publisher:

- [UK Companies House Compliance Monitor](https://apify.com/inhabitable_jingle_clk/companies-house-compliance-monitor) — watch a list of company numbers for overdue accounts and status changes.
- [UK House Price Index by Local Authority](https://apify.com/inhabitable_jingle_clk/uk-house-price-index) — official HM Land Registry averages, index and sales volume.
- [UK Food Hygiene Ratings MCP server](https://mcpize.com/mcp/uk-food-hygiene-ratings) — the same Food Standards Agency API, as tools for Claude, Cursor or any MCP client.
- n8n template: UK bank holiday planner (`22252`). A food-hygiene rating-change alerts workflow (`22159`) is under review; link it here once it is live.

### Data licence and attribution

Contains public sector information licensed under the [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Source: Food Standards Agency, https://ratings.food.gov.uk.

This Actor is independent and is **not affiliated with or endorsed by the FSA**. It uses no FSA logos or rating badge images.

# Actor input Schema

## `businessName` (type: `string`):

Partial name match

## `postcode` (type: `string`):

e.g. LS1 or LS1 4AP

## `localAuthority` (type: `string`):

Council name as listed by the FSA, e.g. 'Leeds' or 'Westminster', or its numeric LocalAuthorityId. Names are looked up from the FSA /Authorities list.

## `businessType` (type: `string`):

e.g. 'Takeaway/sandwich shop', 'Restaurant/Cafe/Canteen', 'Pub/bar/nightclub', or a numeric BusinessTypeId. Partial names work if unique.

## `minRating` (type: `integer`):

Only return businesses with this rating or higher (0-5)

## `maxRating` (type: `integer`):

Only return businesses with this rating or lower (0-5)

## `maxResults` (type: `integer`):

Maximum number of establishments to return

## `monitorKey` (type: `string`):

Name for stored snapshot; enables change detection between runs

## `onlyChanges` (type: `boolean`):

If true, only output establishments that are new or whose rating changed since the last run with the same monitor key

## Actor input object example

```json
{
  "postcode": "LS1 4AP",
  "maxResults": 50,
  "monitorKey": "default",
  "onlyChanges": false
}
```

# Actor output Schema

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

Food hygiene ratings returned by this run (default dataset)

## `summary` (type: `string`):

SUMMARY record: totals, rating counts and change detection info

# 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 = {
    "postcode": "LS1 4AP",
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("inhabitable_jingle_clk/fsa-hygiene-monitor").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 = {
    "postcode": "LS1 4AP",
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("inhabitable_jingle_clk/fsa-hygiene-monitor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "postcode": "LS1 4AP",
  "maxResults": 50
}' |
apify call inhabitable_jingle_clk/fsa-hygiene-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,inhabitable_jingle_clk/fsa-hygiene-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/UxVfAlkWvpfGUhHdC/builds/vKZa43fN1Tsa6yrMr/openapi.json
