Back to documentation
Predictable retry behavior

Delivery retries

Understand when Adal retries delivery, how attempts are scheduled, and how to protect your application from repeated side effects.

Last updated on July 26, 2026 [email protected]
On this page

Overview

Retries give Adal another chance to deliver an accepted webhook when a Destination is temporarily unavailable or returns an error. Adal records the outcome of every attempt and, when the Destination configuration allows it, schedules the next one.

Request → Attempt 1 → Failure → Wait → Attempt 2 → 2xx → Delivered

Retries belong to a specific delivery path. When a Server has multiple Destinations, each one has its own attempts, schedule, and final outcome.

Retries make delivery more resilient, but they do not provide exactly-once delivery or eliminate duplicates. Your Destination must be able to process the same request safely more than once.

Successful and failed attempts

Successful attempts

An attempt succeeds when the Destination returns any HTTP status in the 2xx range. Once Adal receives that response, it does not schedule another automatic attempt for the delivery.

A successful delivery status only means that Adal received the expected HTTP response. It does not prove that the application finished processing the webhook, persisted its data, or completed the intended business operation.

Failed attempts

An attempt fails when the Destination returns a status outside the 2xx range or the request cannot be completed. Common causes include:

  • the Destination returned a 4xx or 5xx response;
  • a network connection could not be established;
  • the request timed out;
  • a DNS or TLS error occurred;
  • Adal CLI could not reach the local service.

A failed result does not necessarily mean the Destination never received the request. The application may have completed its work while the response was lost or arrived after the timeout. A later retry can therefore repeat the same side effect.

Automatic retries

You can configure each Destination to make between 1 and 10 attempts. The configured number includes the initial delivery attempt:

  • 1 attempt — one delivery with no automatic retries;
  • 2 attempts — the initial attempt and at most one retry;
  • 10 attempts — the initial attempt and at most nine retries.

The initial attempt has no additional delay. Adal schedules the next attempt only after the previous one fails. Retries stop when the Destination returns a 2xx response or when the configured attempt limit is reached.

Automatic retries are included in the processing of the original accepted Request and do not consume additional credits.

Retry schedule

After a failed attempt, Adal calculates the delay before the next attempt as follows:

delay = n² minutes

In this formula, n is the number of the next attempt. The delay starts when the previous attempt finishes, not when Adal first accepts the Request.

Next attempt Delay after the previous attempt
Attempt 2 4 minutes
Attempt 3 9 minutes
Attempt 4 16 minutes
Attempt 5 25 minutes
Attempt 6 36 minutes
Attempt 7 49 minutes
Attempt 8 1 hour 4 minutes
Attempt 9 1 hour 21 minutes
Attempt 10 1 hour 40 minutes
Total scheduled delay 6 hours 24 minutes

For example, attempt 2 starts four minutes after attempt 1 finishes. If attempt 2 fails, Adal schedules attempt 3 for another nine minutes later.

The scheduled time is the earliest time at which a retry can begin. The actual delivery may happen later, for example while Adal CLI is disconnected or delivery is temporarily paused.

Waiting for Adal CLI

A disconnected Adal CLI client does not count as a failed attempt. Adal does not start the delivery while the client is offline, so the delivery remains pending and the remaining attempt count is not reduced.

If the scheduled retry time has already passed, the attempt can begin as soon as the CLI reconnects. If that attempt fails, the delay before the next one starts when the failed attempt finishes.

Whether Adal delivers Requests that accumulated while the CLI was offline depends on the Server setting Deliver pending requests on connect:

  • when enabled, stored pending Requests are delivered after the CLI reconnects;
  • when disabled, the CLI receives only new Requests and the earlier deliveries remain pending.

If the CLI is connected but cannot reach the local service, the delivery has already begun. The failure therefore counts as an attempt.

Independent deliveries

For every accepted Request, Adal creates a separate delivery for each Destination connected to the Server. These delivery paths do not block one another and may finish with different results.

Request
├── Destination A → 2xx → Delivered
├── Destination B → 5xx → Retry scheduled
└── Destination C → CLI disconnected → Pending

A successful delivery to Destination A does not cancel the retry for Destination B. A pending delivery to Destination C does not delay the others. The attempt limit is configured separately for each Destination.

Manual retries, cancellation, and Replay

Manually retry a delivery

A manual retry starts another delivery of an existing Request to one selected Destination. It does not create a new Request or affect delivery to any other Destination.

You can manually retry a failed, cancelled, or already successful delivery. Each manual retry consumes 1 credit.

Cancel a pending delivery

You can cancel a delivery while it is pending. Adal will not run the scheduled automatic attempt after cancellation. An HTTP request that is already in progress cannot be recalled, and cancellation does not affect any other Destination.

Replay a Request

Replay creates a new Request from the stored Request and runs the normal delivery flow for every Destination configured for the Server at that time. The original Request remains unchanged. Replay consumes 1 credit.

Action Result Additional credits
Automatic retry Another attempt to one Destination None
Manual retry A new delivery of an existing Request to one Destination 1 credit
Replay A new Request delivered to the current Destinations 1 credit

Duplicates and idempotency

An automatic or manual retry can deliver the same Request more than once. Replay can also repeat the same provider event as a new Adal Request. Your Destination handler should account for both cases.

You can enable the following header separately for each Destination:

X-Adal-Idempotency: <request-key>

Automatic and manual retries of the same Request use the same key. Replay creates a new Request with a new key. For the key to prevent duplicate work, your application must persist processed values and skip the operation when it sees a key it already knows.

If the webhook provider includes a stable event ID, use it for business-level deduplication. Unlike the Adal key, the provider event ID can identify the same external event after Replay.

  • verify the provider signature before processing the request;
  • validate the input;
  • make the handler idempotent;
  • record the stable event ID atomically with the business operation;
  • return a 2xx response only after your application has accepted responsibility for processing the event.

The X-Adal-Idempotency header does not turn delivery into an exactly-once operation. Deduplication and safe retry handling remain the responsibility of the Destination.

Delivery history

Open an accepted Request in the Adal dashboard to inspect its deliveries, grouped by Destination. The technical details available for each attempt include:

  • the Destination and delivery method;
  • the attempt number;
  • the date and time of the attempt;
  • the current status;
  • the HTTP response status, when available;
  • the request duration;
  • details of a network, DNS, TLS, or other delivery error.

A pending status means the outbound request has not started. The pending entry does not consume an attempt until Adal begins the delivery.

Adal does not store response headers or response bodies from Destinations. Delivery history shows the status, timing, and diagnostic details, but not the complete response content.

Limits and lifecycle

  • automatic retries stop at the configured attempt limit;
  • a pending delivery remains available only while the source Request is retained;
  • after the Request data is deleted, the Request cannot be retried or replayed;
  • deleting a Server stops intake, deletes its Destinations, and cancels pending deliveries;
  • manual retries and Replay can repeat side effects in the target application.

Retention depends on the plan and Server configuration. When the retention period ends, Adal permanently deletes the Request together with its delivery history and attempt records.

Retries are not a substitute for your own queues, application logs, monitoring, or recovery mechanisms. Your application remains responsible for tracking the business outcome after it receives the Request.

Troubleshooting

No retry was scheduled

Confirm that the Destination did not return a 2xx response and that the configured attempt limit is greater than the number of the last completed attempt. A Destination configured for one attempt does not retry automatically.

An attempt remains pending for a long time

For Adal CLI delivery, check the CLI connection and the Server setting Deliver pending requests on connect. For Direct HTTP, review the scheduled time of the next attempt and the delivery history.

The Destination processed the event twice

Check whether the application persists the idempotency key or stable event ID before performing irreversible work. Remember that a timed-out attempt may have completed the business operation even though Adal never received its response.

Adal shows a successful delivery, but the operation did not happen

Check the logs and state of the target application. A successful delivery confirms a 2xx HTTP response, not the outcome of the application's internal business operation.

  • Destinations — configure Direct HTTP, Adal CLI, attempt limits, and idempotency keys.
  • Servers — learn about request intake, credits, pending delivery, and Replay.
  • Adal CLI — connect a local application and troubleshoot delivery.
  • Data storage and retention — understand how long Requests and delivery history remain available.
  • Plans and limits — review current limits and credit usage.