Engineering
Designing webhooks that survive your outage
Delivery guarantees are a shared responsibility
Every webhook system makes a promise about delivery. Most promise at-least-once, which is honest, and then leave the consequences to you.
The contract
Each delivery carries an X-GTL-Signature header: an HMAC-SHA256 over the raw request body concatenated with a timestamp, keyed on a secret you rotate yourself. Verify against the raw body, before any JSON parsing — a re-serialised payload will not match.
Deliveries retry five times over thirty minutes with exponential backoff. Any 2xx ends the sequence. A 410 stops it permanently.
What we ask of your handler
- Be idempotent. Every event carries a stable id. Record it and no-op on a repeat.
- Acknowledge fast. Return 200 and do the work on a queue. Handlers that block for eight seconds will eventually time out and get retried, which is worse than not receiving it.
- Tolerate reordering. A retried call.ringing can land after call.completed. Compare the event timestamp against what you already stored.
Why not exactly-once
Because it does not exist across a network boundary. Anyone offering it is doing at-least-once delivery plus deduplication, and deduplication is a decision about your data that belongs on your side.