You don't pay for a crawl.
You pay for a change.
Delta Registry runs 18 production data-extraction pipelines across B2B Data Enrichment, Sanctions & Trade Compliance, Development Finance Procurement, Patent & IP Enforcement, Pharma Safety & Clinical Trials, Government Registers & Procurement, and SEO & Data Pipelines. Every actor is pay-per-event: a run bills you for the records that are actually new, updated, or changed since the last snapshot — not for the pages it had to re-crawl to find them.
Architecture Matrix
18 actors across 7 domains
Every actor below is a separately deployed, independently priced Apify pipeline with its own data source and its own change-detection events. This is the full fleet as it exists on the Apify Store today — not a roadmap.
B2B Data Enrichment
1 actorB2B Lead Enrichment Engine
Global
OpenStreetMap Overpass API + customer seed list (no Google Maps)
Sanctions & Trade Compliance
1 actorMaritime Sanctions Watchdog
Global (OFAC / UN)
OFAC SDN vessel list x UN Security Council Consolidated List (by IMO number)
Development Finance Procurement
1 actorWorld Bank Procurement & Debarment Monitor
Global (World Bank only — ADB / IDB excluded, see docs)
World Bank Procurement Notices API + "Other Sanctions" debarred-firms table
Patent & IP Enforcement
1 actorPatent & IP Enforcement Monitor
US (USPTO) + optional EU (EPO, BYOK)
USPTO PTAB proceedings (IPR/PGR/CBM/Derivation) + optional EPO opposition data
Pharma Safety & Clinical Trials
2 actorsDrug Safety & Recall Monitor
US (FDA) + EU (EMA)
FDA openFDA drug enforcement API + EMA DHPC safety-alert feed
Clinical Trial Data Extractor
Global (ClinicalTrials.gov) + US (FDA Orange Book)
ClinicalTrials.gov API v2 + FDA Orange Book patent/exclusivity data
Government Registers & Procurement
11 actorsAustralian Government Grants Monitor
Australia
GrantConnect (grants.gov.au) — 360,000+ record register, no official API
Cordoba Government Tenders Monitor
Province of Cordoba, Argentina
Province of Cordoba's official public-procurement portal
Chile Official Gazette Monitor
Chile (national)
Diario Oficial de Chile — laws, decrees, resolutions
Entre Rios Government Tenders Monitor
Province of Entre Rios, Argentina
Unidad Central de Contrataciones — Province of Entre Rios
Florida State Procurement Monitor
Florida, United States
MyFloridaMarketPlace (MFMP VBS) — ITB/RFP/ITN/RFI/RSQ solicitations
Mendoza Government Tenders Monitor
Province of Mendoza, Argentina
COMPR.AR-based portal — Province of Mendoza
Buenos Aires Province Tenders Monitor
Buenos Aires Province, Argentina (PBA — not CABA, not national)
PBAC — official procurement portal of Buenos Aires Province
Salta Government Tenders Monitor
Province of Salta, Argentina
Province of Salta's official public-procurement portal
Santa Fe Government Tenders Monitor
Province of Santa Fe, Argentina
Province of Santa Fe portal — ministries and hospitals
Tucuman Government Tenders Monitor
Province of Tucuman, Argentina
Province of Tucuman's official public-procurement portal
UK HSE Enforcement Monitor
United Kingdom
UK Health & Safety Executive — convictions and enforcement notices
SEO & Data Pipelines
1 actorPage Metadata Extractor (CleanMeta)
Global
Any target URL — title, description, canonical, Open Graph, H1, word count
Pay-Per-Event Economic Engine
Every actor in this fleet bills strictly per delivered event — no subscriptions, no seat licenses, no minimum spend. In delta mode, a record that hasn't changed since the last run is never re-delivered and never billed. On Maritime Sanctions Watchdog, only NEW / STATUS_CHANGE / DELISTED events generate a charge — an unchanged vessel record costs nothing on the next run.
Pay for delivered records only. Stop running an actor and the charges stop — nothing recurs in the background.
One price per event type, unlimited concurrent users on your Apify account. Adding teammates costs nothing extra.
A one-off 12-record pull is billed at the same per-record rate as a 50,000-record run. There's no plan tier to graduate into.
An unchanged record in delta mode is never re-delivered to the dataset and never billed — you pay only for what actually changed.
Real example — granular event-type pricing
UK HSE Enforcement Monitor prices two event types separately, so buyers only pay for the depth of data they actually consume:
How the maritime-sanctions actor compares
Figures below are publicly listed Apify Store pricing for named competitor actors, gathered during this project's own market research, plus one off-platform subscription reference point.
| Product | Source | Price | vs. this actor | Scope |
|---|---|---|---|---|
| Maritime Sanctions Watchdog | This project — Apify Store | $0.0005 / record | baseline | OFAC SDN vessel list x UN Security Council Consolidated List (by IMO number) |
| veska/sanctions-pep-screener | Apify Store | $0.035 / record | 70x higher | Persons and companies screened against many sanctions and PEP source lists. |
| lentic_clockss/global-sanctions-screening | Apify Store | $0.003 / record | 6x higher | Persons and companies against multiple lists. Buyer must separately obtain and pay for their own OpenSanctions API key. |
| scrapers_lat/trade-screening-list-scraper | Apify Store | $0.00923 / record | ~18x higher | Broader 7-list trade and sanctions screen. |
| ComplyAdvantage | Off-platform — subscription SaaS | From $99.99 / month | no per-event equivalent | Subscription compliance product. Starting tier covers 100 monitored entities — not sold per record. |
These competitors screen a broader scope — persons and companies against many source lists — while this project's actor performs vessel-specific IMO screening against the OFAC SDN vessel list and the UN Security Council Consolidated List. The precise claim is cheapest vessel-specific sanctions screening found on Apify Store, not the cheapest sanctions screening of any kind.
See live Store pricing →Enterprise Integration Terminal
Every one of the 18 actors across 7 domains is called the same way — through the standard Apify API. There is no separate “enterprise” tier, no SSO, and no dedicated account manager: this is a solo developer’s real, public API, shown below using UK HSE Enforcement Monitor (United Kingdom) as the worked example. Any slug in the fleet reference at the bottom of this section drops into the same three patterns.
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("stefano_seggio/uk-hse-enforcement-monitor").call(run_input={
# actor-specific fields — see the Store page above for this actor's full input schema
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)curl -X POST \
"https://api.apify.com/v2/acts/stefano_seggio~uk-hse-enforcement-monitor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
# Runs the actor synchronously and streams the resulting dataset items straight back —
# no polling required. Swap the slug for any of the 18 actors below.{
"userId": "<yourApifyUserId>",
"createdAt": "2026-09-09T14:32:07.123Z",
"eventType": "ACTOR.RUN.SUCCEEDED",
"eventData": {
"actorId": "<actorId>",
"actorRunId": "<actorRunId>"
},
"resource": {
"id": "<actorRunId>",
"actId": "<actorId>",
"status": "SUCCEEDED",
"startedAt": "2026-09-09T14:28:01.000Z",
"finishedAt": "2026-09-09T14:32:07.000Z",
"defaultDatasetId": "<datasetId>",
"defaultKeyValueStoreId": "<keyValueStoreId>"
}
}
// Illustrative payload shape for the "Run succeeded" webhook event — see Apify's webhook
// docs for the authoritative schema. Configure it per-actor in the Apify Console under
// Actor → Integrations → Webhooks, pointed at a Zapier / Make catch-hook URL or a CRM
// endpoint. That's the real mechanism behind any "CRM integration" — no custom connector.Support runs through the Apify Store issue tracker on each actor’s page — typically a response within ~48 hours, with no formal SLA. That is the real support channel for every actor listed here.
Fleet reference — swap in any of the 18 slugs
grouped by domain- B2B Lead Enrichment Engine
stefano_seggio/actor-18-b2b-lead-magnet$0.002 per lead (+1 more pricing event)
- Maritime Sanctions Watchdog
stefano_seggio/actor-19-maritime-sanctions-monitor$0.0005 per record
- World Bank Procurement & Debarment Monitor
stefano_seggio/actor-20-mdb-procurement-monitor$0.001 per notice record (+1 more pricing event)
- Patent & IP Enforcement Monitor
stefano_seggio/actor-21-patent-ip-enforcement-monitor$0.002 per record (+1 more pricing event)
- Drug Safety & Recall Monitor
stefano_seggio/actor-22-drug-safety-recalls-monitor$0.001 per delivered record - Clinical Trial Data Extractor
stefano_seggio/actor-24-clinical-trials-delta-engine$0.002 per record (+1 more pricing event)
- Australian Government Grants Monitor
stefano_seggio/australia-grantconnect-monitor - Cordoba Government Tenders Monitor
stefano_seggio/cordoba-compras-monitor - Chile Official Gazette Monitor
stefano_seggio/diario-oficial-cl-monitor$0.003 per record - Entre Rios Government Tenders Monitor
stefano_seggio/entrerios-compras-monitor - Florida State Procurement Monitor
stefano_seggio/florida-tenders-monitor$0.003 per full-detail record (+1 more pricing event) - Mendoza Government Tenders Monitor
stefano_seggio/mendoza-compras-monitor - Buenos Aires Province Tenders Monitor
stefano_seggio/pba-tenders-monitor - Salta Government Tenders Monitor
stefano_seggio/salta-compras-monitor - Santa Fe Government Tenders Monitor
stefano_seggio/santafe-compras-monitor$0.003 per full-detail record (+1 more pricing event) - Tucuman Government Tenders Monitor
stefano_seggio/tucuman-compras-monitor - UK HSE Enforcement Monitor
stefano_seggio/uk-hse-enforcement-monitor$0.003 per detail-enriched record (+1 more pricing event)
- Page Metadata Extractor (CleanMeta)
stefano_seggio/page-metadata-extractor$0.0005 per result (never per wasted run)
Infrastructure Telemetry & Delta-Engine Documentation
16 of the 18 actors in this fleet run the delta engine documented below — persisted state, content fingerprinting, and per-record classification against the previous run. The remaining 2 (B2B Lead Enrichment Engine and Page Metadata Extractor (CleanMeta)) are single-pass extractors: there is no previous run to diff against, so there is nothing to fingerprint.
State Fingerprinting
Not every tracked field needs the same treatment. Where the monitored fields are flat scalars — a vessel's sanctions programs, a trial's status string — a direct hash over those fields is already deterministic, since the field set and its order are fixed by the code, not by whatever order the source happened to return them in. Where a monitored field is a genuinely nested object — FDA Orange Book's per-product patent and exclusivity data, for example — a plain hash isn't safe on its own: sorting only the top-level keys leaves a nested object's own key order unsorted.
That gap is not hypothetical. An earlier version of this fleet used exactly that top-level-only JSON.stringify(obj, Object.keys(obj).sort()) on a nested field, and two semantically identical records could still hash differently depending on what order the source API returned a nested object's keys in — producing false STATUS_CHANGE classifications, and a STATUS_CHANGE is a billable event. The fix, used specifically where a tracked field is genuinely nested, is the fully recursive canonicalizer below — it sorts object keys at every nesting level, not just the top one. Flat-field actors hash directly instead; there is no nesting for a recursive step to protect against there.
function canonicalize(value) {
if (Array.isArray(value)) return value.map(canonicalize)
if (value !== null && typeof value === 'object') {
return Object.keys(value)
.sort()
.reduce((acc, key) => {
acc[key] = canonicalize(value[key])
return acc
}, {})
}
return value
}
// The bug this replaced: JSON.stringify(obj, Object.keys(obj).sort())
// only sorts the replacer's TOP-LEVEL key list. Nested objects keep
// whatever key order the source happened to send them in, so two
// semantically identical records could hash differently — and a
// STATUS_CHANGE is a billable event. canonicalize() recurses into
// every array and object first, so key order can never affect the
// fingerprint.
const fingerprint = createHash('sha256') // sha1 on a few older actors
.update(JSON.stringify(canonicalize(monitoredFields)))
.digest('hex')Cross-Run State Persistence
A fingerprint is only useful if it survives past the run that computed it. Apify's run-scoped Actor.getValue() is discarded when the run ends, so the delta engine instead opens a named key-value store — one that persists across every scheduled run of that actor, not just the current one — and reads and writes the last-seen fingerprint for each record key there.
// Run-scoped — discarded when the run ends, useless for diffing
// across scheduled runs:
// await Actor.getValue('LAST_SEEN')
// Named, cross-run store — persists between scheduled runs:
const stateStore = await Actor.openKeyValueStore('delta-state-v1')
const lastSeen = await stateStore.getValue(recordKey)
const classification = !lastSeen
? 'NEW'
: lastSeen.fingerprint === fingerprint
? 'SNAPSHOT_NO_DIFF' // unchanged — never re-delivered, never billed
: 'STATUS_CHANGE' // or an actor-specific event: UPDATED, AMENDED...
await stateStore.setValue(recordKey, { fingerprint, seenAt: Date.now() })Classification
Every record's current fingerprint is compared against the last-seen fingerprint in the named store and classified into one of four outcomes. Three of them are real event names drawn live from this fleet's own deltaEvents lists — grouped below, with a count of how many of the 18 actors emit each one. The fourth, the no-diff case, is deliberately not a delta event at all.
first time this record has ever been seen
fingerprint differs from the last run
actor-specific removal or conclusion event
fingerprint matches the last run — never re-delivered, never billed
Does not appear in any actor's deltaEvents list above — it isn't a delta event, it's the absence of one.
Failure Isolation
A global unhandled-exception handler on process catches both uncaughtException and unhandledRejection before the process exits, and records the stack trace along with memory and run-duration telemetry at the moment of failure — so a crash leaves a diagnosable trail instead of a silent run failure in the Apify Console.
Individual request retries use full-jitter exponential backoff — a random delay bounded by a doubling base and a cap — rather than a fixed retry interval, so a batch of failures doesn't all retry against the source site at the same instant. A request that exhausts its retry budget is written to a dead-letter queue — a named key-value store recording the failure — instead of being silently dropped from the dataset.
process.on('uncaughtException', (err) => captureAndExit(err))
process.on('unhandledRejection', (reason) => captureAndExit(reason))
async function captureAndExit(err) {
await deadLetterStore.setValue('failure-' + Date.now(), {
stack: err instanceof Error ? err.stack : String(err),
memoryMb: Math.round(process.memoryUsage().rss / 1024 / 1024),
durationMs: Date.now() - runStartedAt,
})
process.exit(1)
}
// Full-jitter exponential backoff between retries:
function backoffMs(attempt, base, cap) {
return Math.random() * Math.min(cap, base * Math.pow(2, attempt))
}
// A request that exhausts its retry budget is written here instead
// of being silently dropped from the dataset:
await deadLetterStore.setValue('exhausted-' + recordKey, {
recordKey: recordKey,
attempts: MAX_RETRIES,
lastError: lastError && lastError.message,
})Billing Verification — Real Run Results
The classification logic above only matters if it changes what actually gets billed. These are the two most recent verification passes run against this fleet's own live actors — real runs, real data, not simulated figures.
Maritime Sanctions Watchdog
Global (OFAC / UN)
| Run | Classification result | Billing impact |
|---|---|---|
| Cold run — empty state store | 5 of 5 real OFAC-listed vessels classified NEW | Charged for all 5 records ($0.0025 total at $0.0005/record) |
| Exact repeat run — same input, same state store | All 5 vessels classified SNAPSHOT_NO_DIFF (fingerprint matched the prior run) | $0 charged — 0 chargeable events pushed to the dataset |
| onlyNew re-run, further into the source list | The original 5 were correctly skipped; only genuinely new vessels found further down the list were classified NEW | Billed only for the newly-surfaced vessels — not for the 5 already-seen records |
World Bank Procurement & Debarment Monitor
Global (World Bank only — ADB / IDB excluded, see docs)
| Run | Classification result | Billing impact |
|---|---|---|
| Cold run — empty state store | 3 of 3 real procurement records classified NEW | Charged for all 3 records |
| Exact repeat run — same input, same state store | The same 3 records classified SNAPSHOT_NO_DIFF (fingerprint matched the prior run) | $0 charged — 0 chargeable events pushed to the dataset |
| onlyNew=true re-run | 0 of 3 records delivered — all 3 correctly excluded as already-seen | $0 charged |
Global (World Bank only — ADB / IDB excluded, see docs) — a disclosed scope limit, not a hidden one; see the actor's Store page for the reasoning.