How a webhook gets delivered
Sending a webhook looks like one HTTP POST. In production it's seven steps, built so one customer's broken endpoint never slows down the rest.
Store
Step 1 of 7Write the message to storage before telling your API it was accepted, then record every delivery attempt.
A crash between accepting and sending loses the event, with nothing to retry and nothing to show the customer.
Every message and every attempt is stored, with its request and response, and stays searchable in the delivery logs.
Watch a failed delivery recover
One of three endpoints is down. Attempts follow the real retry schedule, sped up so a day of retries takes a few seconds.
Flip a switch to take an endpoint down or bring it back up, even mid-retry.
What it takes to build this yourself
The usual estimate, before customers start asking for filtering, transformations, and FIFO ordering.
Or let Svix run every box in the diagram
One API call per event. Brex, Recall.ai, and Lob run their webhooks on Svix.
import { Svix } from "svix";
const svix = new Svix("AUTH_TOKEN");
await svix.message.create("customer_123", {
eventType: "invoice.paid",
payload: { invoice_id: "inv_2481", amount: 4200 },
});What does a webhook architecture include?
Storage for every event and attempt, a queue per endpoint, signing, isolated proxies with static IPs, retries with exponential backoff, replay for messages that never succeed, and logs customers can see.
How should webhook retries work?
With exponential backoff. Svix retries immediately, then after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours, and 10 hours before marking the message as failed.
Why send webhooks from static IPs?
Customers behind firewalls need fixed addresses to allowlist. Isolated proxies also stop customer-supplied URLs from reaching your internal network (SSRF).
How are webhooks signed?
With HMAC-SHA256 over the message ID, timestamp, and payload, using a secret per endpoint. Standard Webhooks defines the headers, so receivers can verify with any compatible library.