usend Docs
Webhooks

Retries and replay

How usend retries failed webhook deliveries, and how to replay them.

Retries

A delivery succeeds when your endpoint returns a 2xx status within 20 seconds. Anything else is a failure: a 4xx or 5xx status, a redirect (redirects are not followed), a timeout or a connection error.

Failed deliveries are retried with exponential backoff, up to 13 attempts in total spread over roughly a day. The wait grows quickly: seconds after the first failure, minutes after a few, and hours towards the end.

Every attempt is signed again with a fresh webhook-timestamp, but keeps the same webhook-id, so you can recognize a retry of an event you already processed.

Tip

Make your handler idempotent: store the webhook-id of each processed event and skip it if it arrives again.

Delivery log

Each event sent to a webhook is a delivery. See them in the dashboard on the webhook's page, or with the API:

Shell
curl "https://api.usend.et/webhooks/4dd369bc-aa82-4ff3-97de-514ae3000ee0/deliveries?limit=20" \
  -H "Authorization: Bearer us_123456789"
JSON
{
  "object": "list",
  "data": [
    {
      "id": "2b7c4a51-1f0e-4f6e-9c8a-7d2f3e9a6b10",
      "event_type": "email.delivered",
      "status": "failed",
      "attempts": 13,
      "response_status": 500,
      "last_error": "endpoint returned HTTP 500",
      "created_at": "2026-10-10T09:12:47.118Z",
      "delivered_at": null
    }
  ],
  "has_more": false
}
statusMeaning
pendingNot delivered yet. Attempts may still be in progress.
succeededYour endpoint returned 2xx. delivered_at says when.
failedEvery attempt failed.

attempts counts the attempts made, response_status is the last HTTP status received (null if there was no response), and last_error describes the last failure. Deliveries are kept for 30 days.

Replay a delivery

After fixing your endpoint, send a delivery again:

Shell
curl -X POST https://api.usend.et/webhooks/4dd369bc-aa82-4ff3-97de-514ae3000ee0/deliveries/2b7c4a51-1f0e-4f6e-9c8a-7d2f3e9a6b10/replay \
  -H "Authorization: Bearer us_123456789"

The delivery goes back to pending and is sent again with the original payload and the same webhook-id. You can replay any delivery, including successful ones.

Disabled webhooks

While a webhook is disabled (enabled: false), new events are not recorded for it, and pending retries are not sent. Re-enable it with PATCH /webhooks/{id} and { "enabled": true }, then replay the deliveries you need.