Skip to main content

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

Never do it the other way around (apply side effects first, then record the dedupe key) — a crash between those two steps causes duplicate processing.
1

Verify the signature

Reject immediately if the HMAC or timestamp check fails. Return 401. See Securing Webhooks.
2

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.
3

Check idempotency

Look up event_type + ":" + dedupe_key in your database or cache. If already processed, return 204 immediately — no further action.
4

Apply side effects in a transaction

Update your DB, call downstream APIs, fire queued jobs — whatever your business logic requires.
5

Record the dedupe key

Inside the same transaction as step 4, insert the dedupe record so it’s atomic with your side effects.
6

Return 204 and return fast

Return 204 No Content immediately. If step 4 involves slow operations, enqueue them in a background job and return 204 before they complete.

Dedupe keys

Truedy sends a JSON envelope:
Pick the best available dedupe identifier from data: Composite key fallback:
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


Complete working implementations

Database table for idempotency tracking


Operational runbook

Signature verification fails

  • Log X-Truedy-Timestamp and event (if parseable). Do not log the full secret.
  • Return 401 and 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 204 after 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