Watch & webhooks
Watch turns the register into a stream. Subscribe an entity list or a saved query, and 31 event types arrive a median 4.2 hours after they print in a gazette.
Two kinds of subscription
An ID list watches entities you already hold — your customers, your suppliers, your portfolio. A saved query watches a definition, so the target universe maintains itself: every logistics company in Hamburg with more than 50 employees, whether or not it existed when you wrote the query.
$ curl -s https://api.spotit.ai/v1/subscriptions \ -H "Authorization: Bearer $SPOTIT_KEY" \ -d '{ "query": {"country":"DE","nace":"49.41","headcount_min":50}, "events": ["entity.status_changed","entity.insolvency_filed","query.entered"], "delivery": {"url":"https://example.com/hooks/spotit"}, "backfill_days": 90 }'
query.entered and query.exited fire when an entity starts or stops matching the definition. That is how a sourcing list stops going stale between refreshes.
Verify the signature
Every delivery carries Spotit-Signature: an HMAC-SHA256 of the raw body with your endpoint secret, and a timestamp. Verify before you parse, compare in constant time, and reject anything older than five minutes.
import { createHmac, timingSafeEqual } from "node:crypto"; export function verify(raw: string, header: string, secret: string) { const [t, sig] = header.split(",").map((p) => p.split("=")[1]); if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; const expected = createHmac("sha256", secret).update(t + "." + raw).digest(); const given = Buffer.from(sig, "hex"); return expected.length === given.length && timingSafeEqual(expected, given); }
Delivery, retries and the dead letter queue
- Return a 2xx within 5 seconds. Do the work afterwards — acknowledge, then process.
- Non-2xx or timeout retries at 1 min, 5 min, 30 min, 2 h, 6 h and 24 h with jitter.
- After the last attempt the event moves to a dead-letter queue and stays there for 30 days. GET /v1/events?status=dead lists it.
- Events are at-least-once. Deduplicate on event_id; it is stable across retries.
- You are billed 0.05 credits on successful delivery only. Retries are free, and so are events you never manage to receive.
Replay
Deployed a bad handler on a Friday? POST /v1/subscriptions/{id}/replay re-delivers a window of events, up to 30 days back, at no charge. Replayed events carry replay: true so an idempotent handler can tell them apart in your own logs.
Or poll, if you would rather
GET /v1/events?cursor=… walks the same stream from a cursor you keep. Polling costs nothing, survives a firewall that will not accept inbound webhooks, and is the right choice inside a warehouse job.
The complete list of 31 event types, with annual volumes, is in the API reference.
Try it against your own data
The Developer plan is free forever and needs no card. 2,500 credits is enough to answer the only question that matters: does it resolve your records.