Guides

Retries and recovery

What Dispatch does when a customer's server is slow or down, and how to resend what they missed.

Customers’ servers go down. Dispatch assumes it, so a failed delivery is retried automatically, and a broken endpoint is protected from a flood of retries.

Retry schedule

Dispatch uses the same engine as Gateway. A delivery is attempted immediately, then retried up to 7 more times, after 5 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 2 hours and 4 hours: eight attempts across about seven hours. Each wait is spread randomly so retries don’t land together.

Customer’s response What Dispatch does
2xx Delivered.
408, 409, 425, 429, 5xx, timeout, network error Retries on the schedule.
Other 4xx Fails at once; the endpoint rejected it.
3xx Fails. Redirects are not followed.
Retry-After on 429 or 503 Waits at least that long, never less.
Retry-After: -1 Fails and stops retrying.

Every attempt has a timeout (15 seconds by default).

When an endpoint stays down

After 10 failed attempts in a row an endpoint’s circuit breaker opens. Dispatch stops sending to it, keeps the queue, and probes it after 1 minute, 5 minutes, 30 minutes and then hourly. When a probe succeeds, sending resumes and the queue drains. Other customers are never affected.

An endpoint whose breaker is open shows as such in Customers, so you can tell the customer before they find out themselves. Reset it from the dashboard or with POST /v1/destinations/:id/breaker/reset; changing the endpoint’s URL resets it too.

Retry one message

Resend a message to all of its endpoints, or to a single one:

curl -X POST https://api.getensue.com/v1/dispatch/events/msg_…/retry \
  -H "authorization: Bearer ens_<key>" -H "content-type: application/json" \
  -d '{ "endpoint_id": "dst_…" }'

endpoint_id is optional. A retry creates a new attempt on the same delivery, so the history stays in one place. Retrying a delivery whose endpoint’s breaker is open is refused with 409 breaker_open: reset the breaker first.

Recover an endpoint

When a customer has fixed their server, resend everything it missed in one call:

curl -X POST https://api.getensue.com/v1/dispatch/endpoints/dst_…/recover \
  -H "authorization: Bearer ens_<key>" -H "content-type: application/json" \
  -d '{ "since": "2026-11-09T18:00:00Z" }'
Field Notes
since Required. An ISO 8601 time or milliseconds since the epoch. Goes back at most 14 days.

It retries every failed or cancelled delivery to that endpoint since then, oldest first, up to 500 per call. If there are more, the response sets more: true and gives next_since; call again from there.

{ "retried": 500, "more": true, "next_since": 1767225600000 }

Deliveries then run through the normal delivery policy, at the endpoint’s rate.

Make customers’ lives easier

  • Tell customers to return 2xx as soon as they have verified and stored the webhook, and to process it afterwards.
  • Tell them to de-duplicate on webhook-id; retries and recoveries reuse it.
  • Watch for destination.breaker_opened notifications and reach out first.