# Recall Watch (`matteogenovese/recall-watch`) Actor

Monitor product recall and safety alert pages with keyword filters and alerts.

- **URL**: https://apify.com/matteogenovese/recall-watch.md
- **Developed by:** [Matteo Genovese](https://apify.com/matteogenovese) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Recall Watch

Turn public recall and safety alert pages into short, actionable alerts.

### Why it matters
Most recall pages are noisy, fragmented, and hard to watch manually. This Actor trims the noise and surfaces the bits that matter fast.

### What it does
- watches one or more public recall / safety alert URLs
- extracts readable page text
- keeps the last snapshot for comparison
- highlights likely relevant lines using keywords
- sends optional webhook alerts when a page changes

### Best for
- compliance teams
- brand and product ops
- retailers and distributors
- small teams that need recall visibility without babysitting pages

### Why it wins
- short, actionable diffs instead of raw page-change noise
- tuned specifically for recall and safety alert pages
- webhook-friendly output
- can be narrowed to a brand or category list

### Input
- `urls` — required list of public recall or safety alert URLs, or leave empty and use presets
- `sourcePresets` — optional official presets for `cpsc`, `fda`, `usda`, `nhtsa`
- `keywords` — optional brand, product, or category filters
- `excludeKeywords` — optional filters to cut noise
- `monitorMode` — keep snapshots and compare against the next run
- `dryRun` — skip state writes and webhooks
- `webhookUrl` — optional alert destination
- `webhookFormat` — `generic`, `slack`, or `discord`
- `maxItemsPerPage` — cap extracted hits per source
- `minLineLength` — ignore very short lines
- `userAgent` — custom fetch user agent

### Output
Each dataset item contains:
- URL
- page title
- baseline / changed flags
- change score
- current and previous hashes
- matched keywords
- added / removed lines
- short preview

### Competition
- generic page monitors
- recall email lists
- broad consumer safety alert pages

### Pricing
- launch pricing: $0.49 per monitored page snapshot
- effective from: 2026-07-18
- billing model: pay per event via default dataset items
- primary event: `Monitored page`
- rationale: priced as a narrow recall monitor, not a generic crawler

### MVP scope
This Actor is intentionally narrow:
- no login-heavy portals in v1
- no claims / refunds workflow
- no dashboard UI
- no enterprise case management
- no broad web monitoring platform

### Publish status
- private, ready to publish
- store terms accepted: pending console publish
- last deploy: build `0.1.2`
- known blockers: none yet

# Actor input Schema

## `urls` (type: `array`):

Public recall or safety alert page URLs to monitor. Leave empty if you use source presets.
## `sourcePresets` (type: `array`):

Optional official sources to preload: cpsc, fda, usda, nhtsa.
## `keywords` (type: `array`):

Optional brand, product, or category keywords used to focus the alerts.
## `excludeKeywords` (type: `array`):

Optional keywords that should be filtered out of the extracted lines.
## `monitorMode` (type: `boolean`):

If enabled, the Actor stores snapshots and compares them with the next run.
## `dryRun` (type: `boolean`):

Skip state writes and webhooks while still producing output.
## `webhookUrl` (type: `string`):

Optional webhook destination for change alerts.
## `webhookFormat` (type: `string`):

Payload shape for the webhook.
## `maxItemsPerPage` (type: `integer`):

Maximum number of added or removed lines to include in output.
## `minLineLength` (type: `integer`):

Ignore shorter lines while extracting page text.
## `userAgent` (type: `string`):

Custom user agent used for page fetches.

## Actor input object example

```json
{
  "urls": [],
  "sourcePresets": [
    "cpsc",
    "fda",
    "usda",
    "nhtsa"
  ],
  "keywords": [
    "battery",
    "charger",
    "toy"
  ],
  "monitorMode": true,
  "dryRun": false,
  "webhookFormat": "generic",
  "maxItemsPerPage": 40,
  "minLineLength": 4,
  "userAgent": "recall-watch/1.0"
}
````

# Actor output Schema

## `dataset` (type: `string`):

No description

## `state` (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 = {
    "urls": [],
    "sourcePresets": [
        "cpsc",
        "fda",
        "usda",
        "nhtsa"
    ],
    "keywords": [
        "battery",
        "charger",
        "toy"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("matteogenovese/recall-watch").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 = {
    "urls": [],
    "sourcePresets": [
        "cpsc",
        "fda",
        "usda",
        "nhtsa",
    ],
    "keywords": [
        "battery",
        "charger",
        "toy",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("matteogenovese/recall-watch").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 '{
  "urls": [],
  "sourcePresets": [
    "cpsc",
    "fda",
    "usda",
    "nhtsa"
  ],
  "keywords": [
    "battery",
    "charger",
    "toy"
  ]
}' |
apify call matteogenovese/recall-watch --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Recall Watch",
        "description": "Monitor product recall and safety alert pages with keyword filters and alerts.",
        "version": "0.1",
        "x-build-id": "ZekiZTuzNt1hRTzAX"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/matteogenovese~recall-watch/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-matteogenovese-recall-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/matteogenovese~recall-watch/runs": {
            "post": {
                "operationId": "runs-sync-matteogenovese-recall-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/matteogenovese~recall-watch/run-sync": {
            "post": {
                "operationId": "run-sync-matteogenovese-recall-watch",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "urls": {
                        "title": "URLs",
                        "type": "array",
                        "description": "Public recall or safety alert page URLs to monitor. Leave empty if you use source presets.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "sourcePresets": {
                        "title": "Official source presets",
                        "type": "array",
                        "description": "Optional official sources to preload: cpsc, fda, usda, nhtsa.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "keywords": {
                        "title": "Keywords",
                        "type": "array",
                        "description": "Optional brand, product, or category keywords used to focus the alerts.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "excludeKeywords": {
                        "title": "Exclude keywords",
                        "type": "array",
                        "description": "Optional keywords that should be filtered out of the extracted lines.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "monitorMode": {
                        "title": "Monitor mode",
                        "type": "boolean",
                        "description": "If enabled, the Actor stores snapshots and compares them with the next run.",
                        "default": true
                    },
                    "dryRun": {
                        "title": "Dry run",
                        "type": "boolean",
                        "description": "Skip state writes and webhooks while still producing output.",
                        "default": false
                    },
                    "webhookUrl": {
                        "title": "Webhook URL",
                        "type": "string",
                        "description": "Optional webhook destination for change alerts."
                    },
                    "webhookFormat": {
                        "title": "Webhook format",
                        "enum": [
                            "generic",
                            "slack",
                            "discord"
                        ],
                        "type": "string",
                        "description": "Payload shape for the webhook.",
                        "default": "generic"
                    },
                    "maxItemsPerPage": {
                        "title": "Max items per page",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Maximum number of added or removed lines to include in output.",
                        "default": 40
                    },
                    "minLineLength": {
                        "title": "Minimum line length",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Ignore shorter lines while extracting page text.",
                        "default": 4
                    },
                    "userAgent": {
                        "title": "User agent",
                        "type": "string",
                        "description": "Custom user agent used for page fetches.",
                        "default": "recall-watch/1.0"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
