Webhook Error Handling & Retries
Webhooks are at-least-once: networks fail, servers time out, and Truedy may re-deliver the same event. Your receiver must stay correct even when it sees the same event twice. This guide covers:- The correct processing model
- How to pick a dedupe key
- Response semantics (what status codes to return when)
- Full working implementations in Node.js and Python
The correct processing model
Verify the signature
Reject immediately if the HMAC or timestamp check fails. Return
401. See Securing Webhooks.Parse event and extract a dedupe key
Pull the event type from
envelope.event and the dedupe key from envelope.data. See Dedupe key rules below.Check idempotency
Look up
event_type + ":" + dedupe_key in your database or cache. If already processed, return 204 immediately — no further action.Apply side effects in a transaction
Update your DB, call downstream APIs, fire queued jobs — whatever your business logic requires.
Record the dedupe key
Inside the same transaction as step 4, insert the dedupe record so it’s atomic with your side effects.
Dedupe keys
Truedy sends a JSON envelope:data:
| Priority | Key to use | Event families |
|---|---|---|
| 1st | data.id or data.eventId | Any event that includes it |
| 2nd | data.call.callId (or data.call_id / data.callId) | Call events |
| 2nd | data.batch_id (or data.batchId) | Batch/campaign events |
| 2nd | data.voice_id (or data.voiceId) | Voice training events |
| Fallback | Composite key | If none of the above exist |
Support both camelCase and snake_case variants of identifier fields — Truedy may deliver either depending on the event source. Check
data.callId ?? data.call_id ?? data.call?.callId.Response status codes
| Scenario | Return |
|---|---|
| Signature valid, event already processed (duplicate) | 204 No Content |
| Signature valid, event processed successfully | 204 No Content |
| Signature invalid or timestamp expired | 401 Unauthorized |
| Payload malformed or missing required fields | 400 Bad Request |
| Your DB is down or a transient error occurred | 500 Internal Server Error (triggers re-delivery) |
| Permanent business logic failure (e.g. contact not found) | 204 — record as “handled with error” to avoid infinite retries |
Complete working implementations
Database table for idempotency tracking
Operational runbook
Signature verification fails
- Log
X-Truedy-Timestampandevent(if parseable). Do not log the full secret. - Return
401and stop. - Check: are you reading the raw body before JSON parsing? Body parsers can normalize whitespace and break HMAC.
Payload parse error / schema mismatch
- Log the parsing error and a redacted payload snapshot.
- Return
400.
Transient processing failure (DB down, downstream API timeout)
- Return
500— Truedy will re-deliver the event. - Ensure your handler checks the dedupe table at the start so the retry doesn’t double-process.
Permanent business logic failure
- Return
204after recording the event as “failed but handled” so the retry loop doesn’t run forever. - Alert your on-call team separately.
Next steps
Securing Webhooks
Full HMAC verification code examples
Available Webhooks
Event catalogue and all payload shapes
Idempotency
Platform-wide idempotency patterns

