UK Food Alerts API: Allergy & Product Recall Watch (FSA)
Pricing
from $1.00 / 1,000 alert returneds
UK Food Alerts API: Allergy & Product Recall Watch (FSA)
UK food allergy alerts and product recalls from the Food Standards Agency's public API, or only new and updated alerts since your last run. Never charged for failed or unchanged rows. Not affiliated with or endorsed by the Food Standards Agency.
Pricing
from $1.00 / 1,000 alert returneds
Rating
0.0
(0)
Developer
COMPASS DEV
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Share
Returns UK food allergy alerts and product recalls from the Food Standards Agency's public food alerts API as flat rows, or in watch mode only the alerts that are new or updated since your last run. Never charged for failed or unchanged rows.
Choose alert types (allergy alerts, product recall information notices, food alerts for action) and a window; get one row per alert with the business, products and pack sizes, batch codes and best-before dates, allergens, the risk, what the business is doing, what consumers should do and a link to the alert page. Built for food businesses, retailers, compliance teams, dashboards and AI agents that need UK food alerts without polling the FSA site. Not affiliated with or endorsed by the Food Standards Agency.
What it does
- Export mode: every alert published or updated in the window (default: the last 30 days), one flat row per alert.
- Watch mode (give a watch list name in
stateName): remembers every alert and returns only:baseline: the first run of the list;new: an alert the list did not have (a new alert, or an FSA update with its own-update-Nnumber);changed: the FSA changed an alert (changedFieldsandpreviousValuessay what and from what);- unchanged alerts are free and left out (
includeUnchanged: truereturns them as free rows). - A watch run with nothing new or updated returns exactly one free
no_datarow that says so.
- No personal data, every alert kept: a business name that is, or may be, a person's name (for example a sole trader
trading under their own name) is left out of the alert:
businessloses that name (only that one when several businesses are named) andbusinessOmittedistrue; the name is removed from every other text field, a field that still holds a word of it isnull, and a title that named the person becomes a neutral title such as "Allergy alert: Steak Pie (400g)". When in doubt, the name is removed. The alert itself (products, batches, allergens, risk and advice) is returned and charged like any other. - You are never charged for failed results: failed, no_data and unchanged rows are free.
Quick start
The last 30 days of allergy alerts and product recalls:
{ "alertTypes": ["AA", "PRIN"] }
Watch for new and updated alerts (the first run is the baseline; later runs return only new and updated alerts; run it daily with an Apify schedule):
{ "stateName": "uk-food-alerts" }
Only alerts that name milk or peanut, over the last year:
{ "alertTypes": ["AA"], "allergens": ["milk", "peanut"], "sinceDays": 365 }
Input
| Field | Type | Default | Description |
|---|---|---|---|
alertTypes | list of AA, PRIN, FAFA | all three (prefilled AA, PRIN) | Allergy alerts, product recall information notices, food alerts for action |
sinceDays | integer 1–3,650 | 30 | Alerts published or updated in the last N days |
search | string | — | Optional word or phrase (the FSA API search), e.g. chocolate. Never a URL |
allergens | list of strings | — | Optional: only alerts that name one of these allergens (milk, peanut, sesame, …) |
mode | watch or export | — | Empty: watch when stateName is given, otherwise export. An explicit mode wins |
stateName | string | — (prefilled uk-food-alerts) | Watch list name. Watch mode without a name uses the list default |
includeUnchanged | boolean | false | Watch: also return unchanged alerts (free) |
maxItems | integer 1–100,000 | 1000 | Most charged alerts per run; in watch mode the rest come in the next run |
Field name from other tools: types (→ alertTypes). Changing the types, search or allergens of a watch list starts
a new baseline; changing sinceDays does not.
Output
{"status": "ok","attempts": 1,"error": null,"input": "PRIN","mode": "export","watchList": null,"dropReason": null,"alertId": "FSA-PRIN-45-2026","alertType": "PRIN","alertTypeName": "Product Recall Information Notice","title": "Waitrose recalls Waitrose Essential Unsweetened Oat Drink because of poor temperature control","shortTitle": null,"created": "2026-09-22","modified": "2026-09-22T19:55:28.156Z","alertStatus": "Published","business": "Waitrose","businessOmitted": false,"products": "Waitrose Essential Unsweetened Oat Drink (1 litre)","batches": "Waitrose Essential Unsweetened Oat Drink: …","allergens": null,"riskStatement": "Waitrose recalls Waitrose Essential Unsweetened Oat Drink due to the risk of microbiological contamination and spoilage.","actionTaken": "Waitrose is recalling the above product. …","consumerAdvice": "If you have bought any of the above product, do not eat it. …","countries": null,"previousAlertId": null,"changeType": null,"changedFields": null,"previousValues": null,"url": "https://alerts.food.gov.uk/news-alerts/alert/fsa-prin-45-2026","source": "Food Standards Agency food alerts API. Contains public sector information licensed under the Open Government Licence v3.0 (Food Standards Agency).","license": "OGL v3","licenseUrl": "https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/","scrapedAt": "2026-09-30T12:00:00.000Z"}
| Status | Meaning | Charged? |
|---|---|---|
ok | An alert returned | Export: yes. Watch: baseline, new and changed yes; unchanged no |
no_data | No alert of that type in the window, or nothing new since the last run | No |
failed | Invalid alert type, or no answer after retries (error says why) | No |
The key-value store holds RUN_REPORT (counts, charged and free rows, stop reason) and, when something fails, the raw
response (SNAPSHOT_*).
Use it from AI agents
One clear call: {} returns the last 30 days of every alert type; {"stateName": "<list>"} returns only new and updated
alerts on later calls. Every row has status, error, url and scrapedAt. Call it through the Apify API, the Apify MCP
server (mouadapi/uk-food-alerts) or x402 agentic payments. Copy-paste call (your Apify token in APIFY_TOKEN):
curl -s -X POST "https://api.apify.com/v2/acts/mouadapi~uk-food-alerts/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"alertTypes": ["AA", "PRIN"]}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('mouadapi/uk-food-alerts').call({ alertTypes: ['AA', 'PRIN'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Pricing
Pay per event: one alert event per returned alert (export: every alert; watch: baseline, new and changed rows).
no_data, failed and unchanged rows are free.
| Plan | Price per 1,000 alerts |
|---|---|
| Free | $1.50 |
| Bronze | $1.30 |
| Silver | $1.15 |
| Gold (and higher) | $1.00 |
Apify also charges its small per-run start event. There are no usage fees on top.
Limits
- One request at a time, at most one a second: the FSA publishes no rate limit, so this Actor keeps well under any
reasonable use. If the API answers HTTP 429, the run pauses 60, 120 and 240 seconds on the same connection, then stops
with free
failedrows. No other IP or proxy is ever tried. - At most 1,000 alerts per type and run (the FSA publishes a few dozen alerts a month).
- The FSA's
searchmatches its own text index;allergensuses the FSA's allergen codes (plain words such asmilk).
Known issues
- How names are handled: a business trading under a person's name, and a brand name shaped like a person's name, are left
out of the alert's fields (
businessOmitted: true; the test leans towards removing). Such an alert has a neutral title and may havenullin a text field that repeated the name.RUN_REPORTcounts these alerts (businessNamesOmitted) and the fields set to null (textFieldsNulled), never the names.
FAQ
Does it include every UK food alert? Every alert the FSA publishes in its food alerts API for the types you choose. A business name that may be a person's is left out of the alert's fields (above); the alert is still returned.
Why did a watch run return one no_data row? Nothing was new or updated since the last run of the watch list; the
row says how many alerts were unchanged. It is free.
Data and licence
- Source: the Food Standards Agency food alerts API (data.food.gov.uk), documented at https://data.food.gov.uk/food-alerts/ui/reference.
- Licence: Open Government Licence v3.0 (https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Every row carries the attribution "Contains public sector information licensed under the Open Government Licence v3.0".
- This Actor is not affiliated with, endorsed by or provided by the Food Standards Agency. It returns the alerts as published; always check the linked alert page before acting on it.