Platform

What is a webhook?

A webhook is an HTTP request that one system sends to your application when something happens.

When Bird calls your endpoint, the receiver must preserve the event before work begins. A webhook is an HTTP request that one system sends to your application when something happens. The sender signs the POST to your registered URL. Your receiver decides when the event is durably accepted.

How is a webhook different from polling an API?

Polling means your app calls an API on a schedule and checks for changes. A webhook reverses that direction: the provider calls your endpoint when an event occurs, so you avoid idle requests and react sooner.

Webhooks need a public HTTPS endpoint that can receive requests while events are delivered. Polling works from anywhere and lets your app choose when to fetch state. Use webhooks for timely notifications. Use the API to fetch more resource detail when an event only carries identifiers.

What does a webhook request look like?

A webhook request is an HTTP POST with headers and a JSON event envelope. Bird's email delivery event has type, an event timestamp, and type-specific data:

{
  "type": "email.delivered",
  "timestamp": "2026-06-10T14:30:00Z",
  "data": {
    "email_id": "em_01krdgeqcxet5s7t44vh8rt9mg",
    "recipient_id": "er_01krdgeqcxet5s7t44vh8rt9mg",
    "workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
    "recipient": "user@example.com",
    "recipient_role": "to",
    "tags": [{ "name": "category", "value": "welcome" }],
    "metadata": { "order_id": "ord_123" },
    "broadcast_id": null
  }
}

The message ID is data.email_id. The delivery identity is the webhook-id header, which stays the same when Bird retries or replays that event. The body timestamp records when the event occurred. The webhook-timestamp header records this delivery attempt, so the two timestamps answer different questions. See the email event fields for event-specific payloads.

How do you verify a webhook signature?

Preserve the raw request bytes and verify the signature before parsing or storing the event. Bird's SDK checks the webhook-id, webhook-timestamp, and webhook-signature headers. It applies the timestamp tolerance for you. Use the signature guide instead of writing a second verifier.

If you need to understand the signing input, Bird uses {webhook-id}.{webhook-timestamp}.{raw request body}. The endpoint secret starts with whsec_; remove that prefix and base64-decode the remainder before computing HMAC-SHA256. During secret rotation, the signature header can contain several space-separated v1, values, so accept a matching value from the active secrets.

Reject malformed, unauthenticated, or stale requests before storage. Parsing JSON first can change whitespace or key order and makes the bytes no longer match the signed message.

How should you store and acknowledge a webhook?

Persist a verified event and its durable work before returning success. Insert the event keyed by webhook-id. Insert the work item for a new event. Commit both in one transaction or an equivalent durable inbox and outbox design.

read raw bytes and headers
verify the signature and timestamp with the Bird SDK
begin a durable transaction
  insert the inbox event keyed by webhook-id, unless it already exists
  insert a durable work item for a new event
commit the transaction
return 204
worker processes the persisted event idempotently

A duplicate that is already durably stored can receive 204 without creating more work. Return non-2xx when the durable commit fails, so Bird retries the delivery. Once you return success, retry the local worker from your durable record instead of expecting Bird to send the event again.

This ordering is an application design for Bird's at-least-once delivery semantics. It is not a queue that Bird runs for you. The duplicates and idempotency guide covers the deduplication decision in more detail.

How do webhook retries and replay work?

Bird gives a normal delivery 15 seconds to receive a response. Any 2xx status succeeds. A non-2xx status, redirect, or timeout fails and follows the retry schedule.

Retry after initial attemptBase delay after the previous attempt
15 seconds
25 minutes
330 minutes
42 hours
55 hours
610 hours
710 hours

The curve has 8 attempts including the initial request. Each delay applies plus or minus 20% jitter. A 429 or connection timeout raises the base delay to 60 seconds. A positive Retry-After value is clamped between that base and twice the base before jitter, so the table describes base delays rather than exact arrival times. See how failed webhooks are retried for the failure path.

Deliveries are unordered, so do not update current application state from arrival order alone. Use the event timestamp and your resource state when events can arrive out of order.

When a delivery is missed, inspect webhook attempts. Fix the receiver. Create a webhook replay. Bird skips deliveries the endpoint already received successfully. A replay reuses the original webhook-id, so the same dedupe key protects it.

What should you connect after learning webhook basics?

Create an endpoint. Verify and durably accept its signed deliveries. Inspect delivery attempts. Replay missed events. Then use secret rotation to deploy a new signing secret without dropping deliveries.

Build on the same network.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Your next idea.
Ready to connect.