GMP Enforcement Watch (EudraGMDP + FDA) avatar

GMP Enforcement Watch (EudraGMDP + FDA)

Pricing

Pay per usage

Go to Apify Store
GMP Enforcement Watch (EudraGMDP + FDA)

GMP Enforcement Watch (EudraGMDP + FDA)

Watches your pharma supplier sites across EU and US enforcement sources: EudraGMDP GMP non-compliance reports plus FDA warning letters, with optional FDA inspection classifications via your own free FDA API key. Verbatim regulator wording, provenance deep-links, bounded incremental state.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Atlas

Atlas

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 days ago

Last modified

Share

Marketplace-native Apify Actor for pharma sourcing and QA teams: register your contract API / drug-product manufacturer sites once and get a deduplicated, watchlist-matched feed of GMP enforcement events fused across jurisdictions — with verbatim regulator wording, provenance deep-links to every original document, and bounded incremental state.

Decision-support output only. This Actor reproduces verbatim excerpts from official regulators and adds no interpretation. It is not legal, regulatory or compliance advice, and it does not guarantee completeness of any source. Always verify against the linked official document before acting.

What it watches

SourceJurisdictionEventsAccess model
EU EudraGMDP — GMP non-compliance reports (eudragmdp.ema.europa.eu, public read-only area)EEAStatement-of-non-compliance publications per site: report number, MIA number, OMS location id, address, inspection end date, issue date, verbatim nature-of-non-compliance excerpt from the report detail pageOfficial public search/detail functions used anonymously at a polite ~1 req/s pace with an honest User-Agent. No access controls are bypassed.
US FDA — Warning Letters database (fda.gov)USWarning letters posted inside the window. Two official channels are fused: the live letter index on the database landing page (freshest letters, deep links, FEI) and the paginated Excel export (historical backfill; its cache lags the live DB and aliases page numbers, so backfill depth is bounded by fdaMaxPages). Letters found via the index carry no subject excerpt (it lives on the letter page); export rows carry the regulator's own subject classification. Duplicates across channels are collapsed.Public pages/export fetched anonymously at a polite pace.
US FDA — Data Dashboard API inspections_classifications (optional)USNAI/VAI/OAI inspection classifications for drug facilities in the windowCredential-gated by FDA. Provide your own free registered key via ddapiAuthorizationUser/ddapiAuthorizationKey; without them this source is skipped. Docs: https://datadashboard.fda.gov/oii/api/index.htm

Sources that the underlying opportunity research also mentioned but that are not in v1: FDA import-alert firm lists (their legacy accessdata endpoints were retired; the replacement dashboard is credential-gated), WHO prequalification notices, and national competent-authority pages. These remain explicit future work, not silent gaps.

Input

  • watchlist — array of { "name": "...", "country": "..." }. Matching is deliberately conservative: names are normalized (diacritics, case, legal-form suffixes such as GmbH/S.r.l./ Pvt. Ltd.) and scored by token similarity against each event's site name; a country mismatch on either side blocks a match, and near-tie scores are flagged ambiguous for human review instead of being asserted.
  • modeincremental emits only events not seen in previous runs (default); full re-emits everything found inside the windows (use for backfills/replays).
  • Windows & budgets: euWindowDays, fdaWindowDays, maxDrilldowns (per-run politeness cap on EU detail fetches), fdaMaxPages (each export page = 1000 rows), ddapiMaxRows.
  • minMatchScore (default 0.8) and includeUnmatchedEvents (default true — keep it on: unmatched events make "quiet" periods auditable instead of ambiguous).
  • maxItems caps emitted event records; anything cut off is not committed as seen, so the next incremental run re-emits exactly those.
  • minRequestIntervalMs politeness floor (default 1000).

Output

Dataset records (type):

  1. enforcement_event — one per detected event: stable 40-hex recordId, sourceId, eventType, site name/country/city, eventDate, publishedDate, detailUrl, verbatimExcerpt (capped regulator wording), watchlist match block (matched, matchScore, ambiguous, candidates) and a provenance object (source label, attribution, decision-support notice, fetched endpoints, timestamp).
  2. source_status — one heartbeat per swept source per run (ok, error text, fetched counts, window). Status rows are metadata and never count against maxItems, so a quiet-but-healthy sweep still produces output.

The key-value store holds OUTPUT / LAST_RUN_SUMMARY with per-source stats for monitoring.

Reliability model

  • Per-source failure isolation: one regulator being down never fails the whole run; all sources failing fails loudly after persisting the summary.
  • Retries with exponential backoff honor Retry-After; response size ceilings and timeouts guard every request; parsers are shape-conservative and raise explicit errors on layout changes rather than emitting silently-wrong records.
  • Dataset rows are written before durable state commits; budget-suppressed events stay unseen and re-emit exactly once on replay. State documents are versioned, structurally validated and pruned per source (bounded growth).
  • Zero-result sweeps are visible as fetchedCount: 0 status rows — quiet means quiet, broken means broken.

Compliance posture & known limitations (read before relying on this)

  • Attribution: every record carries source attribution to EMA/EudraGMDP or FDA. EU content originates from EEA National Competent Authorities; US content is U.S. government work.
  • No PPE pricing: this Actor is published without pay-per-event monetization. The underlying research flagged a written EMA confirmation for programmatic access as a precondition for charging customers; that confirmation has not been obtained, so monetization stays off and collection remains plain anonymous public-area browsing at polite rates.
  • Matching is heuristic: name-based entity resolution can miss variants or over-match similar names; country guards and ambiguity flagging reduce but do not eliminate this. Review ambiguous rows before operational decisions.
  • Coverage caveats: FDA warning-letter export pages are consumed oldest-first up to fdaMaxPages — very high-volume windows may need more pages; letters whose posted date cannot be parsed are skipped and counted; deep links resolve only when the landing-page index lists the letter. EudraGMDP excludes information NCAs legally keep non-public.
  • Personal data: outputs carry company/site-level regulatory facts only.

Usage

{
"watchlist": [
{ "name": "Aculife Healthcare Private Limited", "country": "India" },
{ "name": "Avlab S.r.l.", "country": "Italy" }
],
"mode": "incremental",
"euWindowDays": 92,
"includeEuDetails": true,
"fdaWindowDays": 92,
"fdaMaxPages": 2,
"includeUnmatchedEvents": true,
"maxItems": 200,
"minRequestIntervalMs": 1000
}

Run locally: npm install && npm run smoke:local (uses test-input.json). Live smoke test: npm run test:smoke.

Development

npm ci
npm run lint && npm run typecheck && npm run build
npm test # unit + integration + adversarial + schema (no network)
npm run test:smoke # opt-in live-source smoke (SMOKE=1)

Disclaimer

This Actor is an independent tool and is not affiliated with or endorsed by the European Medicines Agency, any National Competent Authority, or the U.S. Food and Drug Administration. Outputs are machine-collected decision support with no compliance, legal or scientific guarantees; users remain responsible for verifying every fact against the linked official sources.