Webhooks
Instead of polling, subscribe an HTTPS endpoint in the console at Developer → Webhooks to the lifecycle events dataquality.<usecase>.sent, .done and .error (batch jobs use the <usecase>-batch slug). Events are notify-only — they carry the job_id, the usecase and the outcome, never the result itself; fetch the result from the poll URL. Every delivery is signed: Delpha-Signature: t=<unix-seconds>,v1=<hex> where v1 is HMAC-SHA256 of "<t>.<raw request body>" under the endpoint's whsec_… signing secret. Verify the signature, reject stale timestamps, and deduplicate on the event id — it is derived from the job and the event type, so a redelivery repeats the same id. A timeout, a 429 or a 5xx from your endpoint is retried up to 3 attempts with exponential backoff (0.5 s, then 1 s); any other 4xx is not retried. The full event shape is the WebhookEvent schema and the three entries under webhooks.
Event families
There are 16 event families — one per operation that admits work, each publishing the 3 lifecycle events sent, done, error. 16 of them are current. The 0 marked deprecated below belong to the deprecated generic LinkedIn operations: they keep delivering for endpoints already subscribed to them, and a new subscription should use the profile and company-page families instead.
email
dataquality.email.sent, dataquality.email.done, dataquality.email.error
current
website
dataquality.website.sent, dataquality.website.done, dataquality.website.error
current
phone
dataquality.phone.sent, dataquality.phone.done, dataquality.phone.error
current
name
dataquality.name.sent, dataquality.name.done, dataquality.name.error
current
legal-id
dataquality.legal-id.sent, dataquality.legal-id.done, dataquality.legal-id.error
current
linkedin-profile
dataquality.linkedin-profile.sent, dataquality.linkedin-profile.done, dataquality.linkedin-profile.error
current
linkedin-company-page
dataquality.linkedin-company-page.sent, dataquality.linkedin-company-page.done, dataquality.linkedin-company-page.error
current
ultimate
dataquality.ultimate.sent, dataquality.ultimate.done, dataquality.ultimate.error
current
email-batch
dataquality.email-batch.sent, dataquality.email-batch.done, dataquality.email-batch.error
current
website-batch
dataquality.website-batch.sent, dataquality.website-batch.done, dataquality.website-batch.error
current
phone-batch
dataquality.phone-batch.sent, dataquality.phone-batch.done, dataquality.phone-batch.error
current
name-batch
dataquality.name-batch.sent, dataquality.name-batch.done, dataquality.name-batch.error
current
legal-id-batch
dataquality.legal-id-batch.sent, dataquality.legal-id-batch.done, dataquality.legal-id-batch.error
current
linkedin-profile-batch
dataquality.linkedin-profile-batch.sent, dataquality.linkedin-profile-batch.done, dataquality.linkedin-profile-batch.error
current
linkedin-company-page-batch
dataquality.linkedin-company-page-batch.sent, dataquality.linkedin-company-page-batch.done, dataquality.linkedin-company-page-batch.error
current
ultimate-batch
dataquality.ultimate-batch.sent, dataquality.ultimate-batch.done, dataquality.ultimate-batch.error
current
Event shape
A lifecycle event delivered to a subscribed endpoint. Notify-only: it names the job and its outcome, never the result — fetch that from the job's poll URL. Deduplicate on id, which is derived from the job and the event type and therefore repeats on redelivery.
id
string
yes
Stable event id — identical on every redelivery of the same event.
type
string
yes
The event scope: dataquality.<usecase>.<sent|done|error>, where <usecase> is the route slug (email, legal-id, linkedin-profile, …) or the slug with a -batch suffix for batch jobs.
created
integer
yes
Unix time (seconds) the delivery was signed — the t of Delpha-Signature.
data
object
yes
What happened, and to which job.
metadata
object
no
The free-form metadata configured on the endpoint, echoed verbatim.
A delivery of dataquality.{usecase}.sent:
Verifying a delivery
Every delivery carries Delpha-Signature. t=<unix-seconds>,v1=<hex> — v1 is HMAC-SHA256 of "<t>.<raw request body>" under the endpoint's whsec_… signing secret (shown once at creation in the console). Recompute it over the raw bytes, compare in constant time, and reject a t older than a few minutes.
Every delivery also sends User-Agent: Delpha-Webhooks/1.0.
Both snippets below reject a delivery whose t is more than five minutes old. That tolerance is a receiver-side choice, not a value Delpha enforces — widen or narrow it to suit your own clock skew.
Python:
Node.js:
Acknowledging
Acknowledge with any 2xx within 10 seconds — that is the delivery timeout, and a slower handler is recorded as a timeout however it ends. Do the work asynchronously and answer first. A redirect is not followed: a 3xx counts as a failed delivery. A timeout, a 429 or a 5xx is retried up to 3 attempts in total, with exponential backoff (0.5 s, then 1 s) — so a failing endpoint is given up on within about two seconds, not minutes; any other 4xx is not retried at all. Delivery is therefore at-least-once with no server-side deduplication: the same event can arrive more than once and your handler must be idempotent on id. Each subscribed endpoint is delivered to independently. Endpoints are managed in the console at https://app.delpha.ai/developer/webhooks.
2XX
Acknowledged — the event is not delivered again.
anything else
Not acknowledged — see the delivery policy above.
Endpoints, their signing secrets and their delivery history are managed at Developer → Webhooks.
Last updated
Was this helpful?