# UK Food Hygiene Ratings Search (`ryanclinton/uk-food-hygiene`) Actor

Search the official UK Food Standards Agency (FSA) food hygiene ratings database covering England, Wales, and Northern Ireland.

- **URL**: https://apify.com/ryanclinton/uk-food-hygiene.md
- **Developed by:** [Ryan Clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 4 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 rating fetcheds

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/platform/actors/running/actors-in-store#pay-per-event

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

## UK Food Hygiene Ratings Search

Search the official UK Food Standards Agency (FSA) food hygiene ratings database covering England, Wales, and Northern Ireland. Retrieve detailed inspection data -- including hygiene, structural, and management sub-scores -- for restaurants, takeaways, cafes, pubs, hotels, supermarkets, and any food business registered with a local authority. No API key required.

***

### Why use this actor?

- **Official government data** -- pulls directly from the Food Standards Agency's FHRS API, the same authoritative source behind the green sticker ratings displayed in business windows across the UK.
- **Zero configuration overhead** -- no API keys, no authentication tokens, no rate-limit management. Provide a search term and get structured results instantly.
- **Granular inspection detail** -- goes beyond the headline 0--5 rating to expose the three underlying sub-scores (hygiene, structural, confidence in management) that inspectors actually assign.
- **Flexible search modes** -- search by business name, address, postcode, GPS coordinates with a mile radius, rating level, or local authority -- or combine any of these for precision filtering.
- **Cloud-native automation** -- runs on Apify infrastructure with built-in scheduling, webhooks, and API access so you can monitor food hygiene trends without maintaining any servers.

***

### Key features

- **Business name search** -- find any food establishment by full or partial name across the entire FHRS database
- **Location-based radius search** -- provide latitude/longitude coordinates and a distance in miles to discover every rated food business within range
- **Address and postcode search** -- search by street address, town name, or UK postcode without needing exact coordinates
- **Rating value filter** -- narrow results to a specific hygiene rating (0 through 5, or Exempt) to isolate top performers or flag problem establishments
- **Local authority filter** -- restrict results to a single council area for focused regional analysis
- **Detailed sub-scores** -- each result includes hygieneScore, structuralScore, and confidenceInManagementScore -- the three components that determine the headline rating
- **Direct FHRS links** -- every result includes a URL to the official ratings.food.gov.uk listing page for verification and reference
- **Automatic pagination** -- seamlessly fetches up to 500 results across multiple API pages in a single actor run
- **Geolocation coordinates** -- latitude and longitude are included for every establishment that has them, ready for mapping and spatial analysis
- **Structured JSON output** -- clean, normalized 20-field records suitable for spreadsheets, databases, dashboards, or downstream processing

***

### How to use

#### Using the Apify Console

1. Go to the [UK Food Hygiene Ratings Search](https://apify.com/ryanclinton/uk-food-hygiene) actor page on Apify
2. Click **Start** to open the input configuration
3. Enter at least one search criterion: a business name, an address/postcode, or latitude/longitude coordinates
4. Optionally set a rating filter, local authority, or adjust max results
5. Click **Start** to run the actor
6. When the run finishes, view or download results from the **Dataset** tab in JSON, CSV, or Excel format

#### Using the Apify API (JavaScript)

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('ryanclinton/uk-food-hygiene').call({
    query: "McDonald's",
    ratingValue: '5',
    maxResults: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Using the Apify API (Python)

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')

run = client.actor('ryanclinton/uk-food-hygiene').call(run_input={
    'query': "McDonald's",
    'ratingValue': '5',
    'maxResults': 100,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

***

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `query` | String | No\* | -- | Business name to search for (e.g., "McDonald's", "Tesco", "Pizza Hut") |
| `address` | String | No\* | -- | Address, town, or postcode to search in (e.g., "Manchester", "SW1A 1AA") |
| `latitude` | Number | No\* | -- | Latitude for geographic proximity search |
| `longitude` | Number | No\* | -- | Longitude for geographic proximity search (must be paired with latitude) |
| `maxDistance` | Number | No | 1 | Maximum radius in miles from coordinates (only applies when latitude/longitude are set) |
| `ratingValue` | String | No | Any | Filter by rating: "0", "1", "2", "3", "4", "5", or "Exempt" |
| `localAuthority` | String | No | -- | Filter by local authority name (e.g., "Westminster", "Birmingham", "Leeds") |
| `maxResults` | Integer | No | 50 | Maximum number of results to return (1--500) |

\*At least one of `query`, `address`, or `latitude`/`longitude` must be provided.

**Example input JSON:**

```json
{
    "query": "Nando's",
    "address": "London",
    "ratingValue": "5",
    "maxResults": 100
}
```

**Tips:**

- Combine `query` with `localAuthority` to search for a chain within a specific council area
- Use the `address` field with a postcode (e.g., "EC1A") for precise geographic targeting without needing coordinates
- Set `maxDistance` only when using latitude/longitude -- it has no effect on name or address searches
- The rating scale runs from 0 (worst) to 5 (best). "Exempt" covers low-risk businesses not rated on the numeric scale

***

### Output

Each item in the output dataset contains 20 fields. Here is a representative example:

```json
{
    "businessName": "Nando's Chickenland Ltd",
    "businessType": "Restaurant/Cafe/Canteen",
    "ratingValue": "5",
    "ratingDate": "2024-06-12",
    "newRatingPending": false,
    "addressLine1": "57-59 Goodge Street",
    "addressLine2": "",
    "addressLine3": "London",
    "addressLine4": "Greater London",
    "postcode": "W1T 1TH",
    "localAuthority": "Camden",
    "longitude": -0.134392,
    "latitude": 51.520847,
    "hygieneScore": 0,
    "structuralScore": 5,
    "confidenceInManagementScore": 0,
    "schemeType": "FHRS",
    "rightToReply": "",
    "fhrsUrl": "https://ratings.food.gov.uk/business/1098765",
    "fhrsId": 1098765
}
```

**Output fields reference:**

| Field | Type | Description |
|-------|------|-------------|
| `businessName` | String | Official registered name of the food business |
| `businessType` | String | Category of business (e.g., "Restaurant/Cafe/Canteen", "Takeaway/sandwich shop") |
| `ratingValue` | String | Overall food hygiene rating: "0" through "5", or "Exempt" |
| `ratingDate` | String | Date of the most recent inspection (YYYY-MM-DD format) |
| `newRatingPending` | Boolean | Whether the business has been re-inspected and awaits a new published rating |
| `addressLine1` | String | First line of the business address |
| `addressLine2` | String | Second line of the address (may be empty) |
| `addressLine3` | String | Third line -- typically the town or city |
| `addressLine4` | String | Fourth line -- typically the county or region |
| `postcode` | String | UK postcode of the business |
| `localAuthority` | String | Name of the local authority responsible for inspections |
| `longitude` | Number/null | Geographic longitude of the business (null if unavailable) |
| `latitude` | Number/null | Geographic latitude of the business (null if unavailable) |
| `hygieneScore` | Number/null | Sub-score for food handling and preparation hygiene (0 = best, 25 = worst) |
| `structuralScore` | Number/null | Sub-score for physical premises condition and maintenance (0 = best, 25 = worst) |
| `confidenceInManagementScore` | Number/null | Sub-score for inspector confidence in ongoing management standards (0 = best, 30 = worst) |
| `schemeType` | String | Rating scheme type -- "FHRS" for England, Wales, and Northern Ireland |
| `rightToReply` | String | Any official response the business has filed regarding its rating |
| `fhrsUrl` | String | Direct link to the establishment's page on ratings.food.gov.uk |
| `fhrsId` | Number | Unique FHRS identifier for the establishment |

***

### Use cases

- **Restaurant due diligence** -- check hygiene ratings before booking venues for events, corporate catering, or business partnerships
- **Franchise investment screening** -- evaluate the hygiene compliance track record of franchise locations before committing capital
- **Property location analysis** -- assess the food safety landscape around a potential commercial or residential property
- **Public health monitoring** -- track hygiene rating trends across a local authority area to identify emerging problem zones
- **Investigative journalism** -- find clusters of low-rated food businesses by area, chain, or business type for data-driven reporting
- **Supply chain compliance** -- verify that food suppliers and distributors maintain acceptable hygiene standards on an ongoing basis
- **Competitor intelligence** -- compare hygiene ratings and sub-scores across competing restaurants in the same market area
- **Tourism and travel apps** -- integrate hygiene ratings into restaurant recommendation engines so users can make informed dining choices
- **Insurance risk assessment** -- factor food hygiene scores into liability risk models for food business insurance underwriting
- **Academic research** -- analyze food safety patterns across geographic regions, business types, or time periods using structured data

***

### API & integration

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')

run = client.actor('ryanclinton/uk-food-hygiene').call(run_input={
    'latitude': 51.5074,
    'longitude': -0.1278,
    'maxDistance': 2,
    'ratingValue': '0',
    'maxResults': 50,
})

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(f"{item['businessName']} - Rating: {item['ratingValue']} - {item['postcode']}")
```

#### JavaScript

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('ryanclinton/uk-food-hygiene').call({
    address: 'Birmingham',
    localAuthority: 'Birmingham',
    maxResults: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach(item => {
    console.log(`${item.businessName} - Rating: ${item.ratingValue}`);
});
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/ryanclinton~uk-food-hygiene/runs" \
    -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
    -d '{"query": "Greggs", "maxResults": 100}'
```

**Platform integrations:** Apify datasets connect natively with Google Sheets, Slack (via webhooks), Zapier, Make (Integromat), GitHub Actions, and any system that can consume JSON via REST API.

***

### How it works

1. **Input validation** -- the actor verifies that at least one search criterion (business name, address, or coordinates) has been provided
2. **Query construction** -- search parameters are assembled into FHRS API query format, including the `fhrs_{value}_en-gb` rating key format when a rating filter is specified
3. **API request** -- the actor calls `api.ratings.food.gov.uk/Establishments` with the `x-api-version: 2` header (no API key needed)
4. **Pagination** -- if results exceed one page (200 items per page), the actor fetches subsequent pages sequentially until the max results limit is reached
5. **Data transformation** -- raw API responses are normalized into clean 20-field output records with parsed coordinates, trimmed strings, and constructed FHRS URLs
6. **Output** -- transformed records are pushed to the Apify dataset for download or API access

```
                         +------------------+
                         |   Input Config   |
                         | (name/addr/GPS)  |
                         +--------+---------+
                                  |
                                  v
                         +------------------+
                         |    Validation    |
                         | (>= 1 criteria) |
                         +--------+---------+
                                  |
                                  v
                    +-------------+-------------+
                    |   FHRS API (Page 1/N)     |
                    | api.ratings.food.gov.uk   |
                    +-------------+-------------+
                                  |
                           +------+------+
                           | More pages? |
                           +------+------+
                          yes|          |no
                             v          v
                      +------+--+  +----+--------+
                      |Fetch N+1|  | Transform & |
                      +------+--+  | Push Data   |
                             |     +----+--------+
                             +--------->|
                                        v
                               +--------+--------+
                               |  Apify Dataset  |
                               | (JSON/CSV/XLSX) |
                               +-----------------+
```

***

### Performance & cost

| Metric | Value |
|--------|-------|
| Memory requirement | 256 MB |
| Typical run time (50 results) | 5--15 seconds |
| Typical run time (500 results) | 20--60 seconds |
| Cost per run (50 results) | < $0.001 |
| Cost per run (500 results) | ~ $0.002 |
| API pages per request | Up to 3 (200 results per page) |
| Maximum results per run | 500 |
| External API keys required | None |
| Rate limiting | None (public government API) |
| Apify Free Plan compatibility | Yes -- hundreds of runs per month within the free $5 credit |

***

### Limitations

- **England, Wales, and Northern Ireland only** -- Scotland uses a separate Food Hygiene Information Scheme (FHIS) with pass/improvement-required ratings and is not covered by this actor
- **Maximum 500 results per run** -- for broader data needs, run multiple targeted searches with different filters or local authorities
- **No historical data** -- the FHRS API returns the current rating snapshot only; it does not provide historical inspection records or rating change history
- **Sub-scores may be null** -- exempt businesses, very old records, and some edge cases lack the detailed hygiene/structural/management sub-scores
- **Dependent on FSA API availability** -- if the Food Standards Agency's API is undergoing maintenance or experiencing issues, the actor will return an error
- **Business type taxonomy is FSA-defined** -- business type labels (e.g., "Restaurant/Cafe/Canteen", "Takeaway/sandwich shop") follow the FSA's own classification and cannot be customized
- **Geolocation coverage varies** -- while most establishments include latitude/longitude, some older records may have null coordinates

***

### Responsible use

- **Public data, public purpose** -- FHRS ratings are published by the UK government for public transparency. Use this data to inform decisions, not to harass or target individual businesses.
- **Verify before acting** -- always check the `newRatingPending` field and the `ratingDate` to understand how current a rating is before drawing conclusions. Businesses may have improved since their last inspection.
- **Respect the rating context** -- a single low sub-score does not tell the full story. Consider all three sub-scores, the overall rating, and whether a new rating is pending before making judgments.
- **No personal data extraction** -- this actor returns business information only. Do not use it in combination with other tools to identify or target individual food handlers or employees.
- **Comply with terms of use** -- while the FHRS API is freely accessible, the underlying data is provided by the UK Food Standards Agency. Any redistribution or commercial use should comply with the [Open Government Licence](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/).

***

### FAQ

**What geographic areas does this actor cover?**
The FHRS database covers England, Wales, and Northern Ireland. Scotland uses the separate Food Hygiene Information Scheme (FHIS) and is not included.

**How current is the data?**
The FHRS API provides near-real-time access to the Food Standards Agency database. Ratings are updated as soon as local authorities publish new inspection results.

**What do the hygiene rating numbers mean?**
Ratings range from 0 to 5: 0 = urgent improvement necessary, 1 = major improvement necessary, 2 = improvement necessary, 3 = generally satisfactory, 4 = good, 5 = very good.

**How do the sub-scores work?**
Each establishment receives three sub-scores: hygieneScore (0--25), structuralScore (0--25), and confidenceInManagementScore (0--30). Lower is better -- 0 is the best possible score in each category.

**What does "Exempt" mean?**
Exempt businesses are those deemed very low risk, such as newsagents selling only pre-packaged food. They are inspected but not rated on the 0--5 numeric scale.

**What does `newRatingPending` mean?**
When `newRatingPending` is true, the business has been re-inspected but the new rating has not yet been published. The displayed rating may be outdated.

**Can I search by postcode?**
Yes. Enter the postcode in the `address` field. For example, setting address to "SW1A 1AA" will return food businesses near that postcode.

**Do I need an API key for the FHRS data?**
No. The Food Standards Agency's FHRS API is freely accessible without authentication. This actor handles all API communication -- you only need an Apify account.

**Why are some coordinate values null?**
Not all establishments in the FHRS database have geocoded locations. Older records or recently registered businesses may be missing latitude/longitude data.

**Can I combine multiple search criteria?**
Yes. You can use `query` together with `address`, `localAuthority`, and `ratingValue` simultaneously to create highly targeted searches.

**What is the maximum number of results I can get?**
A single run can return up to 500 results. If you need more, run multiple searches with different filters (e.g., different local authorities or rating values).

**How is maxDistance calculated?**
The `maxDistance` parameter is measured in miles from the provided latitude/longitude coordinates. It defaults to 1 mile and only applies when coordinates are specified.

***

### Related actors

| Actor | Description |
|-------|-------------|
| [UK Companies House](https://apify.com/ryanclinton/uk-companies-house) | Search UK registered companies, directors, and filing history |
| [UK Police Crime Data](https://apify.com/ryanclinton/uk-police-crime-data) | Search UK police crime records by location |
| [UK Land Registry](https://apify.com/ryanclinton/uk-land-registry) | Search UK property sale prices from HM Land Registry |
| [UK Charity Commission](https://apify.com/ryanclinton/uk-charity-commission) | Search registered UK charities |
| [UK Flood Warnings](https://apify.com/ryanclinton/uk-flood-warnings) | Monitor Environment Agency flood warnings |
| [OpenStreetMap POI Search](https://apify.com/ryanclinton/osm-poi-search) | Find points of interest including restaurants |

# Actor input Schema

## `query` (type: `string`):

Business name to search for (e.g. McDonald's, Tesco, Pizza Hut)

## `address` (type: `string`):

Address, town, or postcode to search in

## `latitude` (type: `number`):

Latitude for location-based search

## `longitude` (type: `number`):

Longitude for location-based search

## `maxDistance` (type: `number`):

Maximum distance in miles for location search (requires latitude/longitude)

## `ratingValue` (type: `string`):

Filter by food hygiene rating value

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

Filter by local authority name (e.g. Westminster, Birmingham, Leeds)

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

Maximum number of results to return (max 500)

## Actor input object example

```json
{
  "query": "McDonald's",
  "maxDistance": 1,
  "maxResults": 50
}
```

# Actor output Schema

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

No description

# 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 = {
    "query": "McDonald's"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/uk-food-hygiene").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 = { "query": "McDonald's" }

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/uk-food-hygiene").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 '{
  "query": "McDonald'\''s"
}' |
apify call ryanclinton/uk-food-hygiene --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/uk-food-hygiene",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/8fYhht8N2FgfoNtyj/builds/L4shYXEzWx2htRWsW/openapi.json
