All endpoints below require an API key. See Authentication.
Lifecycle
- Configure:
PUT /v1/watchlist/webhookwith a URL. DotLookup generates a random 32-byte secret and returns it once in the response — store it; it’s used as the HMAC key and is never returned again. - Receive: After every nightly ETL, DotLookup POSTs the event payload to your URL with an
X-Dotlookup-Signatureheader. Verify the HMAC; respond2xxto acknowledge. - Retry: A non-2xx response triggers retries at 1m, 5m, and 30m. After three failures, the delivery is marked
failedand you can either re-trigger via watchlist catch-up or rotate the URL. - Inspect:
GET /v1/watchlist/webhook/deliveriesreturns the recent attempt log for debugging.
Verify the signature
Every delivery includesX-Dotlookup-Signature: sha256=<hex> — the HMAC-SHA256 of the raw request body using your webhook secret as the key. Reject any request whose signature doesn’t match.
Event payload
The
etl_run_id is the pages step’s etl_runs.id, the same value surfaced on risk-history and the change feed. Receivers can dedupe on (account_id, etl_run_id) if they’re worried about a duplicate delivery from a retry.
Configure the webhook
The
secret field is returned only on initial create or after POST /rotate-secret. Updates that don’t rotate the secret never include it, so it can’t accidentally leak into logs or UI state. Lose the secret? Rotate it.URL validation
v1 blocks only non-http(s) schemes and obvious loopback host literals (localhost, 127.0.0.1, ::1, 0.0.0.0). DNS-resolution-based private-IP filtering is intentionally not enforced — accounts already control their own webhook URL, and operators self-hosting may legitimately point at internal services.
Failure modes
- Non-2xx response or timeout (10s) — retried at 1m, 5m, 30m. After three failures, the delivery row is marked
failed. - Slow receiver — does not block other accounts; dispatch is fanned out across a fixed goroutine pool.
- Process restart during retry window — in-flight retries are lost. Recover via the watchlist changes endpoint to backfill the missing window, or via the email digest which uses a separate idempotency log.