# Ireland FSAI Food and Allergen Alerts (`vixendata/ireland-fsai-food-allergen-alerts`) Actor

Bounded structured alerts from official FSAI pages, with exact advisory context and source attribution.

- **URL**: https://apify.com/vixendata/ireland-fsai-food-allergen-alerts.md
- **Developed by:** [Vixendata](https://apify.com/vixendata) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 recognized consultation/publication/alert metadata records

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

## Ireland FSAI Food and Allergen Alerts

Private, build/test-ready Apify Actor. Reads official Food Safety Authority of Ireland food and allergen alerts. No Apify deployment or paid run is included in this package.

### Run

Python 3.12. Install `pip install -r requirements.txt`, then `python -m src.main` using Apify's local INPUT key-value record, or build the Dockerfile. Actor configuration is `.actor/actor.json`. Offline tests: `python -m unittest discover -s tests -v`.

The direct smoke input in `examples/input-direct.json` requests one known alert. The discovery smoke input visits one food listing and emits at most two details. Runtime additionally requests robots.txt. Default input visits one page each of food and allergen listings and emits up to 20 alerts. Pages contain 10 cards at the time of verification. No browser, proxy, authentication, or challenge solving is used.

### Input and bounded scope

- `alertTypes`: unique `food` / `allergen` values, default both.
- `startUrls`: up to 50 explicit HTTPS www.fsai.ie alert-detail URL strings; default empty.
- `discover`: default true. Set false for direct URLs only.
- `maxListingPages`: 1–5 per stream; default 1. Only actual next-page links are followed.
- `maxItems`: 1–100 output alerts; default 20.
- `issueYears`: optional issue-date years (1990–2100). Applied only to fetched details, with missing dates excluded. This does not search the archive or promise all alerts from a year.
- `requestDelaySeconds`: minimum serial request spacing, 2–60 seconds; default 2. A longer published robots crawl delay is honored.

Discovery visits the bounded listing pages before detail requests. At most 100 discovered listing-card URLs plus 50 direct URLs are candidates. Filters and duplicate records can reduce output. RUN_REPORT records visited URLs and the limited coverage statement. Malformed listing/details and unfiltered empty output fail visibly rather than pretending success. A valid year filter can legitimately produce zero rows. All detail reads complete and every output row validates before dataset writes begin.

### Output and interpretation

One row per source alert, deduplicated by alert type and alert number or normalized detail URL. Food and allergen number streams remain distinct. `issuedDate` is parsed from the displayed issue date; `observedAt` is extraction time in UTC. Missing or unrecognized dates stay null with a warning. No issue date is inferred from observation time or URL.

Published product identification, batch code, message, nature of danger and business/consumer actions are retained as source text with whitespace normalized. `sourceTables` preserves all published table cells; `productRows` exposes tables with a Product column. `packSize`, `approvalNumber`, and `useByDate` extract explicitly labelled values only. All-best-before-date scope remains verbatim in `batchCode`. Where allergens are specified inside a product table, the summary field can say “Please see table below”; consult `productRows` and the full `message`. Advisory qualifications, including possible/unintentional presence and affected consumer groups, are preserved rather than reduced to a misleading allergen list. No medical interpretation is supplied. Always check the linked current official alert before acting.

### Safety and source rights

Only HTTPS www.fsai.ie food/allergen paths are accepted, including redirect destinations. robots.txt must load successfully and allow each request; failures or denial stop the run. Requests are serial, bounded to 5 MB streamed response bodies, with finite timeout and redirect limits. HTTP 401/403/429 and recognizable challenges stop immediately without bypass or retry. No page images, attachments, tracking code, forms, or contact data are fetched.

Source: Food Safety Authority of Ireland (FSAI), © Food Safety Authority of Ireland. Reuse terms: https://www.fsai.ie/re-use-of-public-sector-information . FSAI permits free reuse subject to attribution, accurate reproduction, no misleading use, no principal advertising/promotional use, and no illegal, immoral, fraudulent or dishonest use. FSAI does not warrant currency or error-free information. No endorsement or exclusive rights is implied. Downstream users must preserve these conditions and attribution. The Actor's structured fields do not replace the source.

Fixtures are sanitized official HTML observations from 8 October 2026: two food alerts (2026.61 and 2026.60), one allergen alert (2026.A26), both genuine listings, and a wrong-route Latest News listing retained solely for negative testing. Scripts, forms, inputs, iframes, images and nonessential attributes were removed. Samples are reproducible fixture output, not a deployed Actor run. Official Apify input/dataset metaschemas are vendored under tests/metaschemas and used in tests. No live Apify spend has occurred.

# Actor input Schema

## `alertTypes` (type: `array`):

Food and/or allergen; unique values.

## `startUrls` (type: `array`):

HTTPS www.fsai.ie detail URL strings only, maximum 50.

## `discover` (type: `boolean`):

Visit bounded pages from each selected alert stream.

## `maxListingPages` (type: `integer`):

Maximum pages visited per selected stream.

## `maxItems` (type: `integer`):

Maximum output records.

## `issueYears` (type: `array`):

Optional issue-date year filter on visited pages only. Empty means no year filter.

## `requestDelaySeconds` (type: `integer`):

Minimum serial spacing between requests.

## Actor input object example

```json
{
  "alertTypes": [
    "food",
    "allergen"
  ],
  "startUrls": [],
  "discover": true,
  "maxListingPages": 1,
  "maxItems": 20,
  "issueYears": [],
  "requestDelaySeconds": 2
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("vixendata/ireland-fsai-food-allergen-alerts").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("vixendata/ireland-fsai-food-allergen-alerts").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 '{}' |
apify call vixendata/ireland-fsai-food-allergen-alerts --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vixendata/ireland-fsai-food-allergen-alerts"
        }
    }
}
```

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/FzCqUmRcamwF7LdOK/builds/eJPIeFuu9t8berLuk/openapi.json
