HAREPOST docs Get a key ➔

Retries and delivery

How Harepost retries failed deliveries, backs off, and dead-letters.

When you send a webhook, Harepost queues it and attempts delivery. What happens next depends on how your endpoint responds.

What counts as success

A response with a 2xx status is a success. The delivery is marked delivered and no further attempts are made.

What gets retried

Harepost retries when the failure looks temporary:

  • A 5xx response from your endpoint.
  • A 408 or 429 response.
  • A connection error, or a timeout (your endpoint did not respond within timeout_ms, default 10 seconds).

Each retry waits longer than the last, following your delivery policy, until it either succeeds or runs out of attempts.

What does not get retried

A 4xx response other than 408 or 429 is treated as a deliberate rejection. Your endpoint received the request and refused it, so retrying would just repeat a request you have already declined. The delivery is marked rejected and moved to the dead-letter queue without further attempts.

Backoff and jitter

By default, the delay between attempts grows exponentially: roughly base_delay_ms, then double, then double again, doubling each attempt up to max_delay_ms. With backoff set to fixed, every delay is base_delay_ms instead.

Jitter spreads retries out so a recovering endpoint does not get hit by every pending delivery at the same instant. With the default full jitter, each delay is randomized between zero and the computed backoff ceiling. With none, the delay is exactly the ceiling.

If your endpoint returns a Retry-After header, Harepost honors it instead of the computed delay, unless you set respect_retry_after to false.

When attempts run out

After max_attempts (default 5), a delivery that still has not succeeded is marked dead_letter and moved to the dead-letter queue. Nothing is dropped: the payload and its full attempt history are kept so you can inspect what happened.

Delivery statuses

StatusMeaning
queuedAccepted and waiting for its first attempt.
deliveredYour endpoint returned a 2xx.
retryingAn attempt failed in a retryable way; another is scheduled.
rejectedYour endpoint returned a non-retryable 4xx. In the dead-letter queue.
dead_letterRan out of attempts without success. In the dead-letter queue.

Tuning per request

Every value here is controlled by the delivery object on each send. See the send reference for the fields and their ranges.