# UK FSA Food Safety Alert Portfolio Report (`taroyamada/food-safety-alert-portfolio-report`) Actor

Monitor official UK Food Standards Agency Food Alerts for Allergy Alerts, Product Recall Information Notices, and Food Alerts for Action. Receive source-linked change alerts, portfolio reports, and exports.

- **URL**: https://apify.com/taroyamada/food-safety-alert-portfolio-report.md
- **Developed by:** [naoki anzai](https://apify.com/taroyamada) (community)
- **Categories:** Business
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 food safety alert rows

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 FSA Food Safety Alert Portfolio Report

**Buyer:** food manufacturers, importers, retailers, quality teams, and food-safety consultants who need a bounded change queue from the UK Food Standards Agency. **Input:** alert types, allergen/hazard/product terms, a modified-since or lookback window, and a stable `monitorKey`. **Output:** source-linked change alerts, a portfolio report, and an optional export without business-identity inference.

This actor uses the official, keyless UK FSA Food Alerts JSON API only. The documented source covers Allergy Alerts (`AA`), Product Recall Information Notices (`PRIN`), and Food Alerts for Action (`FAFA`). EU RASFF is intentionally not included because this actor does not rely on an undocumented internal endpoint or scrape a public website.

### Run the next report

- Review cross-agency recall changes with [CPSC & NHTSA Recall Portfolio Watch](https://apify.com/taroyamada/product-safety-market-action-portfolio-report).
- Monitor product recalls with [CPSC Product Recall Marketplace Watch Scraper](https://apify.com/taroyamada/cpsc-product-recall-marketplace-watch-scraper).
- Monitor vehicle recalls and complaints with [NHTSA Recall Complaint Watch Scraper](https://apify.com/taroyamada/nhtsa-recall-complaint-watch-scraper).

### Store Quickstart

1. Run the baseline once with `initialRunMode: "baseline_only"`. It stores the source snapshot and emits zero rows and zero charges.
2. Schedule the same `monitorKey` with `initialRunMode: "emit_current_window"`, `generateReport: true`, and `emitUnchanged: false`.
3. Set a buyer-approved `maxChargeUsd`. A changed run emits the report first, then change alerts, optional raw rows, and an optional export.

#### Example 1: baseline for all alert types

```json
{
  "watchlists": [{ "id": "all-alerts", "alertTypes": ["AA", "PRIN", "FAFA"], "lookbackDays": 30 }],
  "monitorKey": "uk-food-safety-baseline",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitUnchanged": false,
  "maxChargeUsd": 0,
  "dryRun": false
}
```

#### Example 2: allergen and product change watch

```json
{
  "watchlists": [{
    "id": "allergen-products",
    "name": "Allergen product watch",
    "alertTypes": ["AA", "PRIN"],
    "allergens": ["milk", "peanut"],
    "products": ["chocolate", "snack"],
    "lookbackDays": 14,
    "maxResults": 25
  }],
  "monitorKey": "quality-team-allergen-watch",
  "initialRunMode": "emit_current_window",
  "generateReport": true,
  "emitRawRows": false,
  "emitUnchanged": false,
  "emitExport": false,
  "maxChangedRecords": 5,
  "maxChargeUsd": 20,
  "dryRun": false
}
```

#### Example 3: dated hazard report and export

```json
{
  "watchlists": [{
    "id": "hazard-review",
    "alertTypes": ["FAFA", "PRIN"],
    "hazards": ["microbiological", "pathogen"],
    "modifiedSince": "2026-06-01T00:00:00Z",
    "maxResults": 50
  }],
  "monitorKey": "importer-hazard-review",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": true,
  "emitUnchanged": false,
  "emitExport": true,
  "maxChangedRecords": 10,
  "maxChargeUsd": 40,
  "dryRun": false
}
```

#### Example 4: deterministic local dry run

```json
{
  "watchlists": [{ "id": "dry-run", "alertTypes": ["AA"], "allergens": ["milk"], "lookbackDays": 30 }],
  "monitorKey": "dry-run-only",
  "initialRunMode": "emit_backfill",
  "generateReport": true,
  "emitRawRows": true,
  "emitUnchanged": false,
  "emitExport": true,
  "maxChargeUsd": 50,
  "dryRun": true
}
```

### Output and pricing

The first row of a changed run is `food_safety_portfolio_report`. It is followed by `food_safety_change_alert` rows, optional `food_safety_alert` rows, and an optional `food_safety_export` row. Each billable row has a deterministic `stableKey`, `idempotencyKey`, official source URLs, limitations, and prohibited interpretations.

| Event | Price | Emitted when |
| --- | ---: | --- |
| `food-safety-alert-row` | $0.008 | A changed alert is emitted with `emitRawRows: true` |
| `food-safety-change-alert` | $0.25 | A new or changed matched alert is delivered |
| `food-safety-portfolio-report` | $12.00 | A changed run has `generateReport: true` |
| `food-safety-export` | $8.00 | A changed run has `emitExport: true` |

There is no start or heartbeat charge. Baseline-only and fully unchanged runs always produce zero dataset rows and zero charges. The entire unique event plan is checked against `maxChargeUsd` before the first push. A state or delivery failure stops the run and does not advance the baseline.

### Source and compliance boundaries

- Source: `https://data.food.gov.uk/food-alerts/id?_format=json`, documented at `https://data.food.gov.uk/food-alerts/ui/reference`.
- The implementation uses documented JSON query parameters: `since`, repeated `type`, repeated `problem.allergen`, repeated `search`, `_view=full`, `_limit`, and `_sort=-modified`.
- Only FSA API response objects with official publisher metadata and an `items` array are accepted. A malformed or structurally incomplete response is non-billable.
- Only `data.food.gov.uk` API URLs and official FSA/food.gov.uk alert-page URLs are retained.
- This actor does not scrape alert pages, bypass access controls, use private feeds, or require an API key.
- The actor omits reporting-business and other business identity fields. It does not infer a supplier, manufacturer, distributor, or responsible party.
- An alert is evidence for review, not a safety certification, causal finding, legal conclusion, medical conclusion, or proof of harm.
- The actor is not affiliated with or endorsed by the Food Standards Agency or any UK government body.

### See also

Use the source-linked report and qualified internal review for final decisions. This actor is intentionally FSA-only; RASFF, private data, and undocumented endpoints are outside scope.

### Files

- [Input schema](INPUT_SCHEMA.json)
- [Dataset schema](dataset_schema.json)
- [Source compliance](docs/source-compliance.md)
- [Integration guide](docs/integration-guide.md)
- [Competitive snapshot](docs/store-competitive-snapshot.md)
- [Sample output](docs/sample-output.json)

# Actor input Schema

## `watchlists` (type: `array`):

Each watchlist is an independent FSA query and state observation. Filters within a group are OR; supplied filter groups are ANDed locally.

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

Stable state namespace for one recurring portfolio.

## `initialRunMode` (type: `string`):

baseline\_only saves the official snapshot with zero rows; other modes can emit first-run changes.

## `generateReport` (type: `boolean`):

Emit one source-linked portfolio report when selected alerts are new or changed.

## `emitRawRows` (type: `boolean`):

Emit low-priced normalized rows for new or changed official alerts.

## `emitUnchanged` (type: `boolean`):

Include unchanged context only in a run that already contains a real alert change; a fully unchanged run remains free.

## `emitExport` (type: `boolean`):

Emit one compact handoff export when selected alerts are new or changed.

## `maxChangedRecords` (type: `integer`):

Fail closed if the selected change set exceeds this bounded delivery limit.

## `maxChargeUsd` (type: `number`):

All unique planned events must fit before delivery.

## `dryRun` (type: `boolean`):

Uses deterministic fixture output without network, state, or charges.

## `requestTimeoutSeconds` (type: `integer`):

Maximum time allowed for one official FSA request.

## `rateLimitMs` (type: `integer`):

Minimum delay between official source requests.

## `maxRetries` (type: `integer`):

Maximum retry count for transient official source failures.

## `backoffBaseMs` (type: `integer`):

Initial exponential backoff delay after a transient source failure.

## `maxBackoffMs` (type: `integer`):

Maximum exponential backoff delay between retries.

## `delivery` (type: `string`):

Deliver to the default dataset or also copy the completed payload to an HTTPS webhook.

## `webhookUrl` (type: `string`):

Optional HTTPS copy after dataset delivery.

## Actor input object example

```json
{
  "watchlists": [
    {
      "id": "all-uk-alerts",
      "name": "All current UK food alerts",
      "alertTypes": [
        "AA",
        "PRIN",
        "FAFA"
      ],
      "lookbackDays": 30,
      "maxResults": 25
    }
  ],
  "monitorKey": "food-safety-default",
  "initialRunMode": "baseline_only",
  "generateReport": true,
  "emitRawRows": false,
  "emitUnchanged": false,
  "emitExport": false,
  "maxChangedRecords": 25,
  "maxChargeUsd": 1,
  "dryRun": false,
  "requestTimeoutSeconds": 30,
  "rateLimitMs": 250,
  "maxRetries": 2,
  "backoffBaseMs": 250,
  "maxBackoffMs": 4000,
  "delivery": "dataset"
}
```

# 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 = {
    "watchlists": [
        {
            "id": "all-uk-alerts",
            "name": "All current UK food alerts",
            "alertTypes": [
                "AA",
                "PRIN",
                "FAFA"
            ],
            "lookbackDays": 30,
            "maxResults": 25
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("taroyamada/food-safety-alert-portfolio-report").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 = { "watchlists": [{
            "id": "all-uk-alerts",
            "name": "All current UK food alerts",
            "alertTypes": [
                "AA",
                "PRIN",
                "FAFA",
            ],
            "lookbackDays": 30,
            "maxResults": 25,
        }] }

# Run the Actor and wait for it to finish
run = client.actor("taroyamada/food-safety-alert-portfolio-report").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 '{
  "watchlists": [
    {
      "id": "all-uk-alerts",
      "name": "All current UK food alerts",
      "alertTypes": [
        "AA",
        "PRIN",
        "FAFA"
      ],
      "lookbackDays": 30,
      "maxResults": 25
    }
  ]
}' |
apify call taroyamada/food-safety-alert-portfolio-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=taroyamada/food-safety-alert-portfolio-report",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/vAa3Eg9Jrd6dRSYrO/builds/XQFOrrglkdKGFOWV1/openapi.json
