← Stackzilla Blog

Webhook Receivers: Verify, Record, Then Process

Published October 31, 2026 · 3 min read · webhooks, integrations, security, backend

Build webhook handlers that authenticate senders, survive retries, and handle events arriving out of order.

A webhook is a request from another system telling your application that something happened. It is not a guarantee that the event arrived once, arrived in order, or came from the sender named in its JSON. A reliable receiver separates three responsibilities: authenticate the request, durably record the event, and perform the business work. Combining all three into a long synchronous request makes failures harder to reason about. ## Verify the original request Follow the provider's signature specification exactly. Many schemes sign the raw request bytes, so parsing and reserializing JSON before verification can break the signature. Configure the framework to preserve the required raw body for that route. Check timestamps or other replay protections when the provider supports them. Use constant-time comparison where appropriate, keep signing secrets out of logs, and plan for secret rotation. An IP allowlist can be an additional control, but it does not replace the provider's documented authentication mechanism. Limit body size and reject unsupported event types deliberately. A publicly reachable URL should not accept arbitrary work just because the payload has a familiar shape. ## Acknowledge after durable acceptance Persist a verified event with a unique provider event identifier. A uniqueness constraint can turn redelivery into a harmless duplicate rather than another business action. Return the provider's expected successful response once the event is durably accepted. Process expensive work asynchronously so a slow database query or email service does not repeatedly time out the delivery. If durable storage fails, do not claim success and discard the event. Return an appropriate failure so the sender can use its documented retry behavior. Check that behavior rather than assuming every provider retries forever. ## Handle order and uncertainty explicitly An update may arrive before a creation event, or an older state may arrive after a newer one. Decide whether to compare object versions, retrieve current state from the provider, or apply a domain-specific ordering rule. Do not blindly let the last received message win. Arrival order is a network property, not necessarily business chronology. Keep enough information to explain why a particular state transition was accepted. Test duplicate deliveries, invalid signatures, expired timestamps, unknown event types, and a worker crash after applying an effect. Use the provider's test fixtures or development tooling without weakening production verification. Finally, provide an operational replay path with access controls and audit records. Replaying an event should use the same deduplication and safety rules as initial delivery. A webhook endpoint is an integration boundary. Treating delivery as unreliable and identity as something to verify makes that boundary much more predictable. ## Further reading - [Stripe: Webhooks](https://docs.stripe.com/webhooks) - [GitHub: Validating webhook deliveries](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries)

Read the full article on Stackzilla →