Skip to content

How webhook delivery works ​

How Zay delivers events to your endpoints: timeouts, retries, ordering, and when it stops.

Do it: Receive and verify webhooks · Look it up:Webhook endpoints, Event catalog

Timeouts and retries ​

Zay waits up to 30 seconds for your response. Anything outside 2xx, or a network or timeout failure, counts as a failed delivery, and Zay retries on the Standard Webhooks schedule:

0s → 5s → 5m → 30m → 2h → 5h → 10h → 14h → 20h → 24h

That is about three days in total, with ±10% jitter on each delay. Zay honors Retry-After on 429 and 503, capped at 24 hours.

You returnWhat Zay does
2xxSuccess. The delivery is marked succeeded
3xxFailure. Zay does not follow redirects — update your url instead
4xx (not 408 / 429)Permanent failure. The delivery is marked exhausted, no retries
408 / 429Retried on the schedule above
410 GoneThe delivery is marked exhausted and the endpoint is set to disabled at once. Use it to make Zay stop delivering to a URL right away
5xxRetried on the schedule above

Ordering and duplicates ​

  • Ordering is not guaranteed. Two events about the same user or payout can arrive out of order — for example, a retry of an earlier event can land after a later one. Treat each event as a statement about state at its occurred_at; when in doubt, read the resource from the API.
  • Delivery is at least once. The same event may arrive more than once. Deduplicate on the webhook-id header (or the envelope id).
  • Nothing is replayed while an endpoint is disabled. See below.

Endpoint disabling ​

Zay disables an endpoint that keeps failing. This protects both sides: your servers from being hammered while broken, and Zay's delivery pipeline from spending retries on a dead URL.

What counts as a failure ​

  • Any HTTP response outside 2xx, including 3xx redirects.
  • Network errors: connection refused, DNS failure, TLS handshake failure.
  • Timeouts — no response within 30 seconds.

When Zay disables ​

Zay tracks failures per endpoint over a rolling window of several hours. An endpoint that fails repeatedly within that window is set to status: disabled. A single intermittent failure will not disable your endpoint — only a sustained pattern will.

  • Retries of the same event count. One event that runs through its whole retry schedule without succeeding contributes about 9 failures on its own.
  • Successful deliveries between failures do not reset anything — Zay looks at the failure rate over the window, not at consecutive failures. This catches endpoints that flap.
  • Returning 410 Gone disables the endpoint immediately.

While an endpoint is disabled ​

Retrieve webhook endpoint shows status: disabled. No new deliveries are queued for it: events that happen while it is disabled are dropped for that endpoint (your other enabled endpoints still receive them). There is no replay today.

Re-enabling ​

Once you've fixed the problem, set the endpoint back to enabled with Update webhook endpoint, then send yourself a test delivery to confirm it works before the next real event. The failure counter decays over time, so a healthy endpoint starts fresh.