Supplier Sanctions & Debarment Intelligence avatar

Supplier Sanctions & Debarment Intelligence

Pricing

Pay per usage

Go to Apify Store
Supplier Sanctions & Debarment Intelligence

Supplier Sanctions & Debarment Intelligence

Normalized World Bank debarment export, change intelligence, and conservative batch supplier screening.

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

24 days ago

Last modified

Categories

Share

supplier-sanctions-debarment-intelligence turns the official World Bank Listing of Ineligible Firms and Individuals into a normalized, change-aware supplier feed and a transparent batch-screening workflow.

It is built for procurement compliance, supplier onboarding, bid teams, vendor-risk operations, and audit evidence. Instead of a thin table scrape, each successful run can provide:

  • stable entity IDs backed by the World Bank source record ID;
  • normalized names, address/country, debarment period, status, and grounds;
  • deterministic deduplication without merging separate source IDs that happen to normalize alike;
  • exact and conservative fuzzy screening for a supplier batch, with component scores, gates, matched tokens, and country comparison;
  • full, incremental, and diff exports with additions, updates, unchanged records, and removal tombstones;
  • bounded durable state, configuration isolation, single-writer fencing, and immutable snapshots.

Scope: this Actor covers the World Bank list only. It is not a complete sanctions, watchlist, PEP, adverse-media, or legal screening service, and its output is not legal advice. Potential matches require human review.

Authoritative source

The only source is the World Bank Listing of Ineligible Firms and Individuals. The official page states that the list updates every three hours.

At runtime the Actor downloads that page and discovers the production gateway URL and browser API key embedded in its public JavaScript. The key is page configuration—not a private credential—and is never hard-coded, logged, written to a dataset, stored in state, or included in this repository. The discovered URL is accepted only when it exactly matches the expected HTTPS production World Bank gateway host and path.

The gateway response must contain a nonempty, bounded response.ZPROCSUPP array. The Actor parses the official fields including:

  • SUPP_ID, SUPP_NAME, and ADD_SUPP_INFO;
  • SUPP_ADDR, city/state/postal fields, COUNTRY_NAME, and LAND1;
  • DEBAR_FROM_DATE and DEBAR_TO_DATE;
  • INELIGIBLY_STATUS;
  • DEBAR_REASON;
  • LAST_REFRESH_DATE.

An empty, redirected, oversized, non-JSON, malformed, conflicting-duplicate, or schema-invalid response fails closed. Production also requires at least 1,500 normalized entities, a floor backed by the current official feed of roughly 1,523 rows. After the first complete run, the last complete entity count is stored and a later feed below 90% of it is rejected. This relative floor cannot be bypassed through Actor input. No dataset writes, removal inference, OUTPUT, or durable state commit occurs from incomplete source data.

Input

{
"mode": "incremental",
"suppliers": [
{
"referenceId": "ERP-10482",
"name": "Example Engineering Limited",
"country": "Kenya"
},
{
"referenceId": "BID-77",
"name": "Another Supplier"
}
],
"fuzzyThreshold": 0.9,
"maxMatchesPerSupplier": 5,
"includeSourceRecords": true,
"maxSourceRecords": 5000,
"maxScreeningSuppliers": 500,
"stateRetentionDays": 180
}

Modes

  • full: emits every current source entity as snapshot and authoritatively replaces the current digest baseline.
  • incremental: emits only new, updated, and removed source entities.
  • diff: emits current entities as new, updated, or unchanged, plus removals.

Every submitted supplier produces one screening dataset record, including explicit no-match results. includeSourceRecords: false suppresses source rows but still advances source change state after the entire successful run.

maxSourceRecords is a fail-closed source safety cap between 1,500 and 10,000 and participates in the durable configuration hash. Screening queries, match thresholds, output mode, and display choices do not fork source change history. Supplier referenceId values must be unique within a run.

Matching behavior

Exact matching compares the full supplier name after deterministic Unicode, case, punctuation, ampersand, and whitespace normalization.

Fuzzy matching removes common trailing legal-form tokens for comparison and combines:

  • character-bigram Dice similarity;
  • exact token Jaccard overlap;
  • leading-prefix agreement.

A score alone is not enough. Conservative hard gates block explicit country conflicts, very short queries, weak single-token names, multi-token names with no exact token overlap, and numeric-token conflicts. The default threshold is 0.90 and cannot be set below 0.85. Results are candidates for review, not automated clearance decisions.

Country comparison uses the provided country text and the World Bank country name after the same text normalization. Use the official country name when possible.

Dataset output (schema 1.0.0)

The dataset contains two record kinds.

source

Key fields:

  • entityId: SHA-256 of the source namespace and World Bank SUPP_ID; stable across name/address edits;
  • emissionId: retry-stable SHA-256 idempotency key for this logical source emission;
  • sourceRecordId: original World Bank SUPP_ID;
  • entityKey: normalized name/country clustering hint; never used to merge distinct World Bank IDs;
  • name, additionalInformation, normalized name forms, and normalized address;
  • debarment: from, to, optional source status, reason, and isOpenEnded;
  • contentDigest, changeType, and field-level changedFields;
  • sourceUpdatedAt, Actor fetchedAt, and attribution/disclaimer.

A removed record is a tombstone carrying the last durable source representation. Removal means absent from a later complete World Bank response for the same configuration; it does not independently establish that sanctions or debarment no longer apply.

screening

Each input supplier produces:

  • retry-stable emissionId for this logical screening result;
  • stable screeningId and caller referenceId;
  • original and normalized query;
  • matched or no-match;
  • bounded matches with World Bank identity/debarment data;
  • exact or fuzzy match type and deterministic score;
  • component scores, matched tokens, country comparison, and passed gates;
  • for no-match rows, the best rejected candidate and rejection reasons when available.

The OUTPUT key contains the pre-commit run summary, source refresh time, change totals, screening totals, dataset ID, attribution, and the explicit last-state-commit policy. It is intentionally persisted with status: "pending-state-commit" and stateCommitStatus: "pending" because it must be written before state. Only the in-memory return value and successful Actor run report succeeded after the final state save. If state save fails, the Actor fails and persisted OUTPUT remains honestly pending.

Durable consistency and concurrency

State is stored in the named key-value store supplier-sanctions-debarment-intelligence-state-v1, isolated from ephemeral run storage. A named request queue provides a five-minute renewable writer lease. The adapter acquires an authoritative expiry once and renews only within the final half of the lease; frequent per-record fence checks therefore do not repeatedly extend the remote lock. A run that cannot acquire or renew the lease refuses to write, and a locally expired writer is rejected without contacting storage.

Successful state writes create immutable, generation-stamped snapshots; old snapshots are retained up to a bounded count. The state document has an 8 MB safety budget, at most four configurations, and at most 10,000 digest entries per configuration. Before the final authoritative snapshot, state save checks the cached expiry and prolongs only when it is near expiry. After a successful snapshot, the run clears local lease ownership and attempts a best-effort queue unlock so another run can acquire immediately. Queue unlock is cleanup rather than another data/state commit: unlock failure is swallowed after local fencing, does not reverse success, and the last authoritative lease expiry remains the bounded fallback. Failed runs also release a still-valid lease on a best-effort basis.

Commit order is deliberate:

  1. write all dataset records;
  2. write OUTPUT;
  3. assert the writer fence and write the last immutable state snapshot;
  4. clear local lease ownership and attempt a non-throwing queue unlock as cleanup.

If a dataset or OUTPUT write fails, state does not advance. If the last state write fails, a retry may have a different observation-only fetchedAt, but every source and screening dataset row carries a deterministic emissionId that is stable for the same uncommitted baseline and logical result. Consumers should deduplicate or upsert by emissionId; do not use fetchedAt as an idempotency key.

Reliability and limits

Both official requests use 30-second timeouts, bounded exponential backoff with jitter, and up to four retries for network errors, HTTP 429, and HTTP 5xx. Retry-After seconds and HTTP dates are honored up to 30 seconds. Redirects from the gateway are refused. HTML and JSON bodies are streamed through 5 MB and 20 MB caps.

The source currently arrives in one gateway response, so there is no invented pagination contract. All source records are normalized and checked against the absolute and prior-complete-count floors before removal inference or writes begin. Supplier screening is deterministic and bounded to 500 queries, 20 returned matches per query, and 10,000 source rows.

Cost honesty

Each run normally makes two public HTTP requests: one official page request and one official gateway request, plus bounded retries when needed. Matching is local CPU work proportional to supplier count × current World Bank rows; a 500-supplier batch compares against the full list. Apify charges depend on your platform plan, run duration, memory, dataset writes, and storage retention. This Actor cannot promise a fixed run price. Incremental mode can reduce dataset writes, while screening cost remains proportional to the submitted batch.

Submitted supplier names and optional countries are written to the run dataset as audit evidence. Do not submit data you are not authorized to process.

Development and verification

Requires Node.js 22.

npm ci
npm run lint
npm run typecheck
npm run build
npm test
npm run smoke:local
npm run smoke:live
npm run validate:schema
npm audit --audit-level=high
npm run audit:source

npm run check runs every non-network check. The adversarial suite covers discovery changes, hostile/ambiguous discovery, response envelopes, absolute and relative completeness floors, malformed rows/JSON, retry exhaustion and Retry-After, normalization collisions, fuzzy false positives, caps, configuration isolation, authoritative full-baseline replacement, retry-stable emission IDs, honest pre-commit OUTPUT, write ordering/failures, lease contention/expiry, final-write snapshots, schema validation, and a complete local smoke pipeline. The opt-in live smoke uses only the official World Bank page and gateway.

Local Actor smoke

After building, run through the simulated Apify environment:

$npx apify run --purge --input '{"mode":"full","suppliers":[],"includeSourceRecords":false}'

You can also place input in local storage and run npx apify run.

Attribution

Source: World Bank, “Listing of Ineligible Firms and Individuals.” The World Bank controls the source content, update timing, availability, and interpretation. Review the official page, applicable World Bank rules, and qualified legal/compliance guidance before making procurement or eligibility decisions.