For AI agents
Let your AI assistant or your own software watch FDA recalls for you. Three ways in, all with the same API key: an MCP server, a REST API and webhooks.
Access is by request for now. Once you're approved, make a key on your account page under For AI agents and your own software. Each key belongs to your account and can be removed at any time.
1. MCP server
The address is https://recallfirst.com/mcp and every request sends Authorization: Bearer rf_….
Claude Code
claude mcp add --transport http recall-first https://recallfirst.com/mcp \ --header "Authorization: Bearer rf_YOUR_KEY"
Cursor, Claude Desktop and other apps that take a JSON config
{
"mcpServers": {
"recall-first": {
"url": "https://recallfirst.com/mcp",
"headers": { "Authorization": "Bearer rf_YOUR_KEY" }
}
}
}
Apps that only accept sign-in by OAuth, such as custom connectors in Claude.ai or ChatGPT, can't use a key yet. Use the REST API or webhooks with those for now.
| Tool | What it does |
|---|---|
| add_watch | Watch words, firms, categories, a class and states. Returns how many recalls from the last 90 days already match. |
| list_watches | Your watches. |
| remove_watch | Stop a watch. |
| list_matches | Recalls that matched, newest first, with why. Pass since to get only new ones. |
| get_recall | One recall's full record and its FDA link. |
| search_recalls | Search recent recalls by word, category and class. |
Try asking: "Watch for any recall of kratom or tianeptine sold in New Jersey, and tell me what's matched this month."
2. REST API
KEY=rf_YOUR_KEY
# Add a watch
curl -s https://recallfirst.com/v1/watches -H "Authorization: Bearer $KEY" -H 'content-type: application/json' \
-d '{"name":"Supplements","terms":["kratom","ashwagandha"],"categories":["food"],"min_class":2,"states":["NJ","NY"]}'
# What matched since yesterday
curl -s "https://recallfirst.com/v1/matches?since=2026-10-21T00:00:00Z" -H "Authorization: Bearer $KEY"
# One recall
curl -s https://recallfirst.com/v1/recalls/F-0123-2027 -H "Authorization: Bearer $KEY"
| Call | What it does |
|---|---|
| GET /v1/watches | Your watches. |
| POST /v1/watches | Add a watch: name, terms, firms, categories (food, drug, device), min_class (1 to 3), states. |
| PUT /v1/watches/{id} | Change a watch. |
| DELETE /v1/watches/{id} | Remove a watch. |
| GET /v1/matches | Matches, newest first. Optional: since (ISO time), watch_id, limit (up to 200). |
| GET /v1/recalls | Search: q, category, class, limit. |
| GET /v1/recalls/{id} | One recall. |
3. Webhooks
Save an https address on your account page. Each hour that something new matches, we POST it there once:
{
"event": "recall.matched",
"sent_at": "2026-10-22T14:23:05.000Z",
"matches": [{
"watch": { "id": 12, "name": "Supplements" },
"why": ["mentions \"kratom\""],
"recall": { "id": "F-0123-2027", "classification": "Class I", "firm": "…", "product": "…",
"reason": "…", "distribution": "Nationwide", "date": "2026-10-21", "url": "https://…" }
}]
}
Check that it came from us: the X-RecallFirst-Signature header is sha256= followed by the HMAC-SHA256 of the raw body, keyed with the secret shown when you saved the address.
import hmac, hashlib
def from_recall_first(raw_body: bytes, header: str, secret: str) -> bool:
want = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(want, header)
We try each delivery once. If your server was down, read what you missed with GET /v1/matches?since=….
For crawlers and agents
A plain summary of this page is at /llms.txt.