Food Supplier & Regulatory Intelligence
Pricing
from $35.00 / 1,000 supplier profile screeneds
Food Supplier & Regulatory Intelligence
US food supplier/product screening Actor: one-shot scan of a roster against FDA openFDA food enforcement and USDA FSIS recalls plus Safe & Suitable Ingredients. Emits evidence-linked supplier_exposure and ingredient_reference records. Not a general web scraper; not medical or legal advice.
Pricing
from $35.00 / 1,000 supplier profile screeneds
Rating
5.0
(1)
Developer
Vamsi Krishna
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 hours ago
Last modified
Categories
Security
Limited permissionsShare
Apify Actor identity: US food supplier/product screening in scan or monitor mode against FDA openFDA food enforcement and USDA FSIS recalls / Safe & Suitable Ingredients. Official APIs only — not a general web scraper, and not medical or legal advice.
What does Food Supplier & Regulatory Intelligence do?
This Actor screens a US food supplier and product roster against official FDA openFDA food enforcement and USDA FSIS recall and ingredient APIs, then writes evidence-linked Dataset records (supplier_exposure, ingredient_reference) plus a run summary. Use mode=scan for a one-shot screen of the lookback window, or mode=monitor for scheduled change-detection against a namespaced baseline. It is a screening support tool for importers, distributors, and manufacturers — not a regulatory certification, legal opinion, or guarantee of complete recall coverage.
Official sources used:
- FDA openFDA Food Enforcement
- USDA FSIS recalls API
- USDA FSIS Safe & Suitable Ingredients (Directive 7120.1 Table 2)
Why use Food Supplier & Regulatory Intelligence?
Use it when you need a repeatable, API-friendly way to check whether roster firms or products appear in recent US recall/enforcement data — without inventing evidence or collapsing severity into name-match confidence.
Highlights
- Screens against FDA food enforcement, FSIS recalls, and FSIS Safe & Suitable Ingredients in one run
- Deterministic matching: exact identifiers → exact name → aliases → fuzzy + context, with explicit confidence levels
- Regulatory severity is independent of match confidence (a Class I recall with a weak name match stays a weak match)
- Every alert-like Dataset item carries an official
sourceUrlwhen the source provides one - Monitor mode diffs against a persisted named-KV baseline and emits only new or materially changed exposures
- Runs on Apify with scheduling, API access, Dataset/KV storage, and spend limits via pay-per-event
Audience: food importers, distributors, manufacturers, and developers integrating supplier risk workflows.
What data can it extract?
| Field | Type | Description |
|---|---|---|
recordType | string | supplier_exposure (recalls/enforcement) or ingredient_reference (FSIS ingredients) |
source | string | FDA_FOOD_ENFORCEMENT, USDA_FSIS_RECALLS, or USDA_FSIS_INGREDIENTS |
officialRecordId | string | Stable official id (e.g. FDA recall_number, FSIS recall number) |
supplierMatch | object | Matched roster supplier, match type, confidence, reasons |
productMatch | object | Optional matched roster product / brand |
regulatorySeverity | string | Mapped regulatory class/risk (independent of match confidence) |
recall | object | Firm, product, reason, status, dates, distribution |
ingredient | object | Safe & Suitable substance / reference notes (ingredient hits only) |
evidence.sourceUrl | string | Link back to the official record or API evidence |
evidence.matchedFields | array | Which fields contributed to the match |
detectedAt | string | UTC timestamp when the Actor emitted the record |
changeType | string | Monitor only: new, material_change, or baseline (null in scan) |
currentFingerprint / previousFingerprint | object | Monitor material fingerprints (classification, status, reason, matchedProducts, recordType) |
changedFields | array | Fingerprint field names that differ (material_change only) |
stateNamespace | string | Monitor namespace that owns the named-KV baseline |
Key-value store (default run store): SCAN_SUMMARY (counts, truncation, sourceErrors, sourceFreshness, and for monitor: changeTypeCounts, baselineEstablished, stateNamespace, namedStore) and optional source snapshots. Monitor baselines live in a separate named store fsri-state-{namespace} (keys BASELINE, META) — not only in the run’s default store.
How to screen suppliers against FDA and FSIS data
- Open the Actor in Apify Console and go to the Input tab.
- Set
regiontoUSandmodetoscan(ormonitorfor change-detection — see below). - Choose sources (FDA food enforcement, FSIS recalls, and/or FSIS ingredients).
- Paste your suppliers and products roster (ids, legal names, aliases, optional FEI/UPC).
- Set
lookbackDays,matchThreshold, andmaxRecordsas needed. - For monitor: set a stable non-
defaultstateNamespace(one per customer/watchlist). - Start the run. Download results from the Dataset (JSON, CSV, Excel, etc.) and inspect
SCAN_SUMMARYin the run’s key-value store.
You can also start runs from the Actor API tab (or any Apify client) with the same JSON input.
How to use monitor mode
Monitor compares each run’s matches to a persisted baseline and pushes only new or materially changed exposures.
- Set
modetomonitorand choose a stable non-defaultstateNamespace(one per customer/watchlist). - Keep the same roster and same
stateNamespaceon every subsequent run. - First run with
emitBaselineMatches: false(default): writesBASELINE+METAinto named storefsri-state-{namespace}and pushes 0 Dataset items;SCAN_SUMMARY.baselineEstablishedistrue. - Later runs: unchanged matches are suppressed (
SCAN_SUMMARY.changeTypeCounts.unchanged). New official actions or material fingerprint edits appear aschangeType: "new"or"material_change". - To dump the first-run match set into the Dataset instead of a silent baseline, set
emitBaselineMatches: true(items taggedchangeType: "baseline").
Monitor rejects empty namespaces and the literal default. Isolation is namespace-only: do not share namespaces across tenants. The named store fsri-state-{namespace} is created in the Actor user’s Apify account.
Schedule monitor on Apify
Use an Apify Schedule with a stable stateNamespace and the same roster on every tick. Example daily cron (UTC):
- Cron:
0 6 * * *(every day at 06:00 UTC) - Actor input (illustrative — fill
suppliers/productswith your roster):
{"region": "US","mode": "monitor","stateNamespace": "acme-watchlist","emitBaselineMatches": false,"lookbackDays": 365,"sources": ["FDA_FOOD_ENFORCEMENT","USDA_FSIS_RECALLS","USDA_FSIS_INGREDIENTS"],"suppliers": [],"products": [],"matchThreshold": "strong","maxRecords": 1000}
Keep stateNamespace and the supplier/product roster identical across scheduled runs so the baseline stays meaningful.
How much will it cost?
Pricing uses Apify pay-per-event (PPE). The Actor charges the custom event supplier-profile-screened once per supplier successfully screened in a run (scan or monitor — including silent baseline runs), with spend-limit stop when the platform reports the charge limit reached.
Event prices are configured in Apify Console for this Actor — this README does not invent public unit prices. Compute units may also apply depending on run size and platform plan. Check the Actor's pricing tab in Console for current rates and free-tier allowances.
Input
See the Input tab for the full schema. Important fields:
| Field | Notes |
|---|---|
region | US only in this MVP |
mode | scan (one-shot) or monitor (baseline diff / change-detection) |
lookbackDays | How far back to include FDA/FSIS recall/enforcement records |
sources | Multiselect of FDA / FSIS recalls / FSIS ingredients |
suppliers / products | Roster objects with ids, names, aliases, optional identifiers |
matchThreshold | Emission floor for match confidence (default strong / legacy 85) |
maxRecords | Cap on Dataset items (monitor: cap applies to pushed deltas); truncation in SCAN_SUMMARY |
openFdaApiKey | Optional secret; raises openFDA rate limits |
stateNamespace | Required for monitor: unique tenant/watchlist id; not empty or default. Opens fsri-state-{namespace} |
emitBaselineMatches | Monitor first run: false = silent baseline (0 pushes); true = emit all current matches as baseline |
Output
You can download the Dataset in JSON, HTML, CSV, or Excel. Example supplier_exposure item (simplified):
{"recordType": "supplier_exposure","source": "FDA_FOOD_ENFORCEMENT","officialRecordId": "F-0001-2026","supplierMatch": {"name": "Example Food Ingredients Inc","supplierId": "sup-001","matchType": "exact","matchConfidence": 1.0,"reasons": ["Exact firm name match"]},"regulatorySeverity": "Class I","recall": {"firm": "Example Food Ingredients Inc","product": "Example Protein Product","reason": "Undeclared allergen (milk)."},"evidence": {"sourceUrl": "https://api.fda.gov/food/enforcement.json?search=recall_number:%22F-0001-2026%22","matchedFields": ["firm"]}}
Ingredient hits use recordType: "ingredient_reference" and never carry recall severity.
Monitor deltas add nullable fields on pushed items:
changeType | Meaning |
|---|---|
new | Stable id absent from the prior baseline |
material_change | Fingerprint fields differ (see changedFields, previousFingerprint, currentFingerprint) |
baseline | First-run emit when emitBaselineMatches is true |
Unchanged matches are not pushed. Material fingerprint fields: classification, status, reason, matchedProducts, recordType.
Tips and limitations
- US coverage only. Canada/EU sources are out of scope for this MVP.
- FDA openFDA food enforcement updates on a roughly weekly cadence (
meta.last_updated). Very fresh FDA actions may lag. CheckSCAN_SUMMARY.sourceFreshnessfor per-source cadence / as-of timestamps. - FSIS recalls are fetched as a full corpus per run, then filtered client-side by lookback. Prefer caching/snapshots for large repeated scans. Freshness for the FSIS corpus is also reported under
sourceFreshness. - FSIS / Akamai: FSIS JSON APIs often return HTTP 403 without browser-like
User-AgentandSec-Fetch-*headers. This Actor sends those polite defaults. Residual IP/TLS or WAF blocks still appear underSCAN_SUMMARY.sourceErrors— never as fabricated evidence. - Monitor isolation: one
stateNamespaceper customer/watchlist; named store lives in the Actor user’s account. Do not share namespaces. If a source hard-fails with zero records, prior baseline ids for that source are retained (fail-closed merge) so a later healthy fetch can still surface news. - Raise precision by supplying legal names, aliases, FEI, UPC/GTIN, and linked products; fuzzy firm matches without context are not treated as confirmed supplier risk.
- Lower
maxRecords/ shorterlookbackDaysto limit run size; PPE charging stops further screening when the spend limit is reached. - Matching quality gates in CI apply only to the labeled fixture set in
tests/fixtures/labeled_matching_cases.json— not a claim of production accuracy.
FAQ, Disclaimers, and Support
Is this a regulatory certification?
No. Output is screening support for your own due diligence. It does not certify supplier safety, compliance, or fitness for a regulated purpose. Consult qualified regulatory or legal advisors for decisions that require certification. This disclaimer applies equally to scan and monitor output.
Does severity equal match confidence?
No. regulatorySeverity (e.g. Class I) describes the official action. supplierMatch.matchConfidence describes how strongly the official record relates to your roster entry. A severe recall with a weak name match is still a weak match.
Why might FDA results look behind?
openFDA food enforcement is typically refreshed about weekly. Use lookbackDays and inspect SCAN_SUMMARY.sourceFreshness (and related source timestamps) when timing matters.
Why do FSIS calls sometimes fail?
FSIS endpoints sit behind Akamai. Clients without compatible headers often get 403; this Actor sets defaults, but network/WAF blocks can remain. Failures are recorded in sourceErrors without inventing sourceUrl evidence.
How does monitor / schedule mode work?
Set mode to monitor with a stable non-default stateNamespace. The first run establishes a baseline in named KV store fsri-state-{namespace} (silent unless emitBaselineMatches is true). Later runs push only new or materially changed exposures (changeType new | material_change). Schedule the Actor on Apify with the same namespace and roster. Unchanged matches are suppressed; see SCAN_SUMMARY.changeTypeCounts.
Matching quality
Automated tests assert high-confidence (exact/strong) precision ≥ 95% on the labeled fixture set, that labeled positive alert-like outputs include sourceUrl, and that dedupe keys still suppress duplicate (source, officialRecordId, supplier) emissions. Those metrics are fixture-scoped and must not be marketed as production accuracy.
Personal data and ethics
This Actor queries public official regulatory APIs and matches them to the roster you provide. Do not submit personal data you are not entitled to process. If results could contain personal data from official notices, handle them under applicable privacy laws (including GDPR where relevant) and only with a legitimate purpose.
Support
- Use the Actor Issues tab on Apify Store for bugs and feature requests
- Use the API tab for programmatic runs and Dataset access
- Review
SCAN_SUMMARY/sourceErrorsbefore treating an empty Dataset as “all clear” (especially after a silent monitor baseline)