# UK Food Hygiene Ratings Scraper (`muhammadafzal/uk-food-hygiene-ratings-scraper`) Actor

Search official Food Standards Agency FHRS/FHIS data and return one structured record per UK food establishment. Filter by name, postcode/address, radius, rating, scheme, local authority, business type, or exact FHRS ID across England, Wales, Northern Ireland, and Scotland.

- **URL**: https://apify.com/muhammadafzal/uk-food-hygiene-ratings-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.50 / 1,000 food hygiene rating results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Scraper

**UK Food Hygiene Ratings Scraper** searches the official Food Standards Agency (FSA) Food Hygiene Rating Scheme (FHRS) and Food Hygiene Information Scheme (FHIS) API and returns one structured dataset item per UK food establishment. It is designed for local restaurant research, food-safety monitoring, compliance workflows, property and location analysis, lead enrichment, and AI agents that need current public hygiene-rating records.

### What this actor does

Use it when you need official hygiene ratings for restaurants, cafes, takeaways, pubs, hotels, supermarkets, schools, or other food businesses in England, Wales, Northern Ireland, or Scotland. Search by business name, address or postcode, coordinates and radius, rating, scheme, local authority, business type, or exact FHRS ID. The actor uses the FSA API directly, so it does not need browser automation, cookies, or an API key.

The default input searches for `restaurant` and returns up to 25 records. Results are capped before charging, and the actor uses the FSA-recommended paged requests of 200 records or fewer with configurable flow control.

### Output and price

Each returned establishment costs **$0.0025 per result**, plus Apify platform compute according to your selected billing model. A small 25-result search therefore has a typical result-event charge of **$0.0625**, excluding platform compute. The actor stops before emitting a record when the per-run result cap or PPE event limit is reached.

The dataset contains `businessName`, `ratingValue`, `ratingKey`, `schemeType`, `ratingDate`, `newRatingPending`, address fields, postcode, phone, FSA scores when supplied, coordinates, distance, local authority details, `fsaUrl`, `apiUrl`, and `scrapedAt`. A run summary is written to the `OUTPUT` key-value record with counts, pages, warnings, and the FSA source.

### When to use it

- Find all food businesses with a particular rating near a UK postcode or coordinate.
- Monitor a restaurant group, local authority, town, or business category.
- Retrieve exact records when you already have FHRS IDs.
- Build a local food-safety dataset for dashboards, research, or AI workflows.
- Enrich a list of venues with the latest public rating and inspection date.

This actor is for FHRS/FHIS establishment data. It is not a restaurant review scraper, menu scraper, food-delivery scraper, or general business directory scraper.

### Input

All fields are optional. The default `searchQuery` is `restaurant`.

| Field | Description |
| --- | --- |
| `searchQuery` | Business-name keyword, such as `The Golden Lion` or `pizza`. |
| `address` | Street, town, city, or UK postcode, such as `B1 1AA`. |
| `latitude`, `longitude` | Decimal coordinate pair for a radius search. |
| `radiusMiles` | Coordinate-search radius from 0.1 to 100 miles; default 5. |
| `establishmentIds` | Exact FHRS IDs, such as `[80928, 1865746]`; when present, search filters are ignored. |
| `schemeType` | `FHRS` for ratings or `FHIS` for Scotland information statuses. |
| `rating` | FHRS value such as `5` or FHIS status such as `Pass`. |
| `ratingOperator` | `Equal`, `GreaterThanOrEqual`, or `LessThanOrEqual` for numeric FHRS ratings. |
| `businessTypeId` | Official FSA business-type identifier. |
| `localAuthorityId` | Official FSA local-authority identifier. |
| `countryId` | Official FSA country identifier. |
| `sortBy` | `Relevance`, `rating`, `desc_rating`, `alpha`, `desc_alpha`, or `distance`. |
| `maxResults` | Maximum records and maximum result-event charges; 1–1000, default 25. |
| `pageSize` | FSA page size; 1–200, default 100. |
| `requestDelayMs` | Delay between requests; 100–10000 ms, default 500. |

For an exact record lookup:

```json
{
  "establishmentIds": [1865746]
}
```

For nearby five-star businesses:

```json
{
  "searchQuery": "",
  "address": "",
  "latitude": 51.5074,
  "longitude": -0.1278,
  "radiusMiles": 2,
  "rating": "5",
  "sortBy": "distance",
  "maxResults": 50
}
```

### Output example

```json
{
  "fhrsId": 1865746,
  "businessName": "The Golden Lion",
  "businessType": "Restaurant/Cafe/Canteen",
  "address": "10 High Street, Cambridge, CB2 1AA",
  "postcode": "CB2 1AA",
  "ratingValue": "5",
  "ratingKey": "fhrs_5_en-gb",
  "schemeType": "FHRS",
  "ratingDate": "2026-07-29T00:00:00",
  "newRatingPending": false,
  "localAuthorityName": "Cambridge City",
  "fsaUrl": "https://ratings.food.gov.uk/business/1865746"
}
```

### How to use it from code

JavaScript with the Apify client:

```js
const run = await apifyClient.actor('YOUR_USERNAME/uk-food-hygiene-ratings-scraper').call({
  searchQuery: 'pizza',
  address: 'Birmingham',
  rating: '5',
  maxResults: 25,
});
const { items } = await apifyClient.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python with the Apify client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("YOUR_USERNAME/uk-food-hygiene-ratings-scraper").call({
    "searchQuery": "cafe",
    "address": "Leeds",
    "maxResults": 20,
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(items)
```

### Data source, freshness, and limitations

The source is the public **Food Standards Agency FHRS API v2**. The FSA data reflects the hygiene standards found at the date of inspection or visit; a food hygiene rating is not a guide to food quality. Records may have `newRatingPending: true`, and FHRS IDs can change when local authorities change or merge source databases. The source is updated by the FSA and participating local authorities, so the actor does not guarantee a particular update time or coverage for an individual authority.

The FSA applies traffic shaping. HTTP 403 and 429 responses can mean the service is throttling requests. This actor retries transient responses with exponential backoff and adds a configurable delay between pages, but a large run can still receive a partial result. Check the `OUTPUT` key for warnings. For full nightly authority downloads, use the FSA open-data files rather than repeatedly querying the live API.

Use the FSA data according to the [FSA open-data terms and guidance](https://ratings.food.gov.uk/open-data?lang=en-US) and the [FHRS API documentation](https://api.ratings.food.gov.uk/Help). Do not present a rating as a food-quality or safety guarantee, and direct questions about a specific business to the responsible local authority.

### Related Apify data tools

Explore related categories and dedicated actors for [restaurant data](https://apify.com/actors?search=restaurant), [Google Maps leads](https://apify.com/actors?search=Google%20Maps), [business directories](https://apify.com/actors?search=business%20directory), [local business data](https://apify.com/actors?search=local%20business), [postcode data](https://apify.com/actors?search=postcode), [location intelligence](https://apify.com/actors?search=location%20intelligence), [compliance data](https://apify.com/actors?search=compliance), and [public records](https://apify.com/actors?search=public%20records).

### FAQ

#### Is an API key required?

No. The FSA documents this as a public API with no registration requirement. The actor sends the required API-version header and handles ordinary throttling responses.

#### Can I search by postcode?

Yes. Put the postcode in `address`, for example `B1 1AA`. You can also combine an address with a name keyword.

#### Can I retrieve a single business?

Yes. Supply its FHRS ID in `establishmentIds`, for example `[1865746]`. This uses the direct FSA establishment endpoint.

#### Why did I receive fewer results than requested?

The FSA may return fewer matches than the cap, a filter may be restrictive, the source may be throttling, or the actor may have stopped after a diagnostic failure. Inspect `OUTPUT.warnings`, `totalMatchingRecords`, and `pagesFetched`.

#### What is the difference between FHRS and FHIS?

FHRS provides numeric hygiene ratings in England, Wales, and Northern Ireland. FHIS is the information scheme used in Scotland and can return statuses such as `Pass`, `ImprovementRequired`, or `AwaitingInspection`.

# Actor input Schema

## `searchQuery` (type: `string`):

Use this when searching by a food business name or keyword. Free text is matched against business names; example: 'The Golden Lion' or 'pizza'. Defaults to 'restaurant'. Do not use this for a postcode-only search; use address instead.

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

Use this when searching a street, town, city, or UK postcode. Example: 'B1 1AA' or 'Cambridge'. Searches business addresses and postcodes. Leave blank when using exact FHRS IDs.

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

Use this with longitude to search around a geographic point. Decimal degrees, for example 51.5074. Both latitude and longitude are required for a radius search; do not provide only one coordinate.

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

Use this with latitude to search around a geographic point. Decimal degrees, for example -0.1278. Both coordinates are required for a radius search; do not provide only one coordinate.

## `radiusMiles` (type: `number`):

Use this to limit a coordinate search to a radius in miles. Accepts 0.1 to 100 and defaults to 5 when coordinates are supplied. Ignored unless latitude and longitude are supplied.

## `establishmentIds` (type: `array`):

Use this for exact record lookups when you already know the Food Hygiene Rating Scheme IDs. Enter integers such as \[80928, 1865746]. When supplied, search filters are ignored and records are fetched directly.

## `schemeType` (type: `string`):

Use this to select the official scheme. 'FHRS' is the hygiene rating scheme used in England, Wales, and Northern Ireland; 'FHIS' is the food hygiene information scheme used in Scotland. Defaults to FHRS.

## `rating` (type: `string`):

Use this to filter by an FHRS rating such as '5', '4', or '0', or an FHIS status such as 'Pass' or 'ImprovementRequired'. Example: '5'. Leave blank to include all ratings.

## `ratingOperator` (type: `string`):

Use this with numeric FHRS ratings to choose the comparison: Equal, GreaterThanOrEqual, or LessThanOrEqual. Defaults to Equal. It has no effect on non-numeric FHIS statuses.

## `businessTypeId` (type: `integer`):

Use this to filter by the FSA business type identifier, for example restaurants, takeaways, schools, or supermarkets. Supply an integer from the official BusinessTypes endpoint. Leave 0 for all business types.

## `localAuthorityId` (type: `integer`):

Use this to restrict results to one UK local authority. Supply an integer from the official Authorities endpoint. Leave 0 to search all authorities.

## `countryId` (type: `integer`):

Use this to restrict results to a country record from the official Countries endpoint. Supply an integer ID; leave 0 for all UK countries.

## `sortBy` (type: `string`):

Use this to choose result order. Supported values are Relevance, rating, desc\_rating, alpha, desc\_alpha, and distance. Defaults to Relevance; distance is most useful with coordinates.

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

Use this to cap the number of establishments returned and the maximum number of per-record charges. Accepts 1 to 1000 and defaults to 25. Tighten this for an agent lookup; raise it for bounded local research.

## `pageSize` (type: `integer`):

Use this to control each FSA API page. Accepts 1 to 200 and defaults to 100. The API recommends paging at 200 or below to reduce throttling; this is not the final result cap.

## `requestDelayMs` (type: `integer`):

Use this to add flow control between FSA API requests. Accepts 100 to 10000 milliseconds and defaults to 500. Increase it if the FSA API returns 403 or 429 throttling responses.

## Actor input object example

```json
{
  "searchQuery": "The Golden Lion",
  "address": "B1 1AA",
  "latitude": 51.5074,
  "longitude": -0.1278,
  "radiusMiles": 2,
  "establishmentIds": [],
  "schemeType": "FHRS",
  "rating": "5",
  "ratingOperator": "Equal",
  "businessTypeId": 7845,
  "localAuthorityId": 123,
  "countryId": 1,
  "sortBy": "Relevance",
  "maxResults": 50,
  "pageSize": 100,
  "requestDelayMs": 1000
}
```

# Actor output Schema

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

Link to the dataset containing one normalized record per food establishment.

# 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 = {
    "searchQuery": "restaurant"
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/uk-food-hygiene-ratings-scraper").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 = { "searchQuery": "restaurant" }

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/uk-food-hygiene-ratings-scraper").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 '{
  "searchQuery": "restaurant"
}' |
apify call muhammadafzal/uk-food-hygiene-ratings-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/uk-food-hygiene-ratings-scraper"
        }
    }
}

```

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/ymoSWxqLMxVn5U0rg/builds/1saHs36CRgtdy2x3B/openapi.json
