Sending a webhook looks simple: make an HTTP request to the recipient’s URL. In production, the request itself is only the beginning.
The recipient may be temporarily unavailable. DNS resolution or a TLS handshake may fail. A request may time out after the recipient has already processed it. Reliable delivery needs a queue, a retry policy, and a clear record of what happened—without allowing a repeated attempt to quietly create a second payment, order, or notification.
Today we are introducing Adal Outbound, a dedicated outbound delivery service from Adal. Your application gives Adal the destination URL, method, headers, and body. Adal queues the message, delivers it, retries failed attempts, and records the result of each one.
Your application → Adal Outbound → Destination URL
Outbound is separate from the inbound webhook flow in Adal. It does not require a Server, Request, or Destination from that flow. It is a standalone API for applications that send webhooks to customers, partners, and external services.
An HTTP client is only the first step
The ideal path is short: your application sends a request and receives 200 OK. Real delivery has many more possible outcomes:
the recipient is unavailable for a few seconds or several minutes;
the connection opens, but no response arrives before the timeout;
the recipient returns
429,500, or another non-success status;the recipient processes the request, but the response is lost in transit;
DNS resolution or the TLS handshake fails;
the delivery timeline needs to be reconstructed after an incident.
Adal Outbound brings the complete delivery pipeline into one service: a queue, workers, retry scheduling, state tracking, attempt logs, metrics, and delivery diagnostics. Your application sends the message to the selected Adal region. Adal takes care of what happens next.
How Adal Outbound works
During initial setup, your application uses an Outbound token created in the dashboard to obtain an access token and a refresh token. It can fetch the list of available regions once, select the right region, and store that region’s domain in its configuration.
Messages are then sent directly to the selected region. When the access token expires, the application obtains a new one with the refresh token. The region list is independent of token renewal and only needs to be refreshed when required—for example, to discover a new region or change where messages are sent.
Each call to /api/send accepts:
destination— required; the recipient’s public HTTP or HTTPS URL;method— required; the HTTP method to use;headers— optional; the HTTP request headers;body_base64— optional; the request body encoded as Base64;max_attempts— optional; the maximum number of delivery attempts.
For example:
POST https://kz2.adal.cloud/api/send
Authorization: Bearer <access-token>
Content-Type: application/json
{
"destination": "https://example.com/webhooks",
"method": "POST",
"headers": {
"Content-Type": ["application/json"],
"X-Event-Id": ["evt_01K2..."]
},
"body_base64": "eyJldmVudCI6Im9yZGVyLmNyZWF0ZWQifQ==",
"max_attempts": 3
}
Adal responds with 202 Accepted, a message ID, the selected region, and an initial status of pending. This means Adal has accepted the message and queued it for delivery. It does not mean that the recipient has received it yet.
From that point on, Adal manages delivery and records the outcome of every attempt.
Predictable retry scheduling
A delivery succeeds when the recipient returns a 2xx HTTP status. A connection error, timeout, or any other status triggers another attempt until the configured limit is reached.
Adal makes up to three attempts by default. Each message can be configured with a limit from one to ten attempts. After failed attempt N, the delay before the next attempt is calculated as:
delay = N² minutes
The first failed attempt is followed by a one-minute delay, the second by four minutes, and the third by nine minutes if the configured limit allows another attempt. This schedule gives a temporarily unavailable service time to recover without sending retries too aggressively.
Automatic retries do not consume additional credits. Credits are charged once, when Adal accepts the message for delivery.
At-least-once delivery and recognizable retries
Outbound uses an at-least-once delivery model. In a distributed system, it is not always possible to tell whether the recipient failed to process a request or processed it successfully but lost the response. Under some failure conditions, the same HTTP request may therefore be delivered more than once.
A stable event identifier or idempotency key can be included in the message so the recipient can distinguish another attempt from a new event. Adal preserves that value in the supplied headers or body across delivery attempts.
Adal evaluates delivery at the HTTP layer: a 2xx status means the recipient returned a successful response. The recipient’s internal business logic remains outside the Adal transport layer.
A delivery history that explains failures
The dashboard shows the current status and attempt history for every message. Depending on the result, an attempt can include:
the HTTP response status and headers;
technical error details;
DNS timing;
connection and TLS timing;
time to first byte and total request duration;
TLS connection information;
the redirect chain and final URL.
These details make it possible to separate a DNS failure from a TLS issue, a slow application response, or an unsuccessful HTTP status. Instead of a generic “webhook delivery failed” message, the team gets a timeline of individual attempts.
Adal does not store or display the recipient’s HTTP response body. Message and attempt history is currently available through the dashboard rather than the public API.
You choose the delivery region
Every message is sent directly through the Adal region selected by your application. The destination URL, method, headers, body, and delivery history are stored in that region. The Control Plane handles authentication and region discovery, but it is not a centralized store for Outbound message history.
Explicit region selection is useful when network routing, processing geography, or organizational data-location requirements matter. Choosing a region alone does not establish compliance with a particular law or industry standard. That assessment depends on the data involved, applicable agreements, and the requirements governing the organization.
Adal infrastructure already operates in several countries, and we plan to expand its geographic coverage. Applications can retrieve the current region list during initial setup and refresh it independently of message delivery.
Adal does not automatically select a region or fail over between regions. The application specifies the region for each message. If your project needs a region that is not yet in the public list or requires dedicated infrastructure isolation, contact us. We will review the requirements and assess the available configuration.
Destination URL security
Outbound makes requests to user-supplied URLs, so Adal validates each destination and applies SSRF protections. Only public HTTP and HTTPS URLs are accepted. localhost, private and special-purpose IP ranges, and URLs containing embedded usernames or passwords are rejected. The destination is validated again after an HTTP redirect.
Outbound is therefore designed to deliver messages to publicly reachable HTTP services. It does not send directly to 127.0.0.1, private IP addresses, or internal hostnames.
Where Outbound fits
Adal Outbound can support any application that sends HTTP events to an external system. For example:
a SaaS product sends events to customer webhook URLs;
a platform notifies partners when an order or payment changes;
an internal service sends events to the public API of a CRM, help desk, or another platform;
a product uses the managed Adal queue and retry scheduler for its integrations;
a team needs one observable history of outbound deliveries;
different message flows need explicit control over delivery and storage regions.
The current Outbound flow is deliberately direct: one request to Adal creates one message for one recipient, and the application specifies the region when sending it.
Get started
Create an Outbound token under Outbound → Tokens, obtain an access token and a refresh token, retrieve the region list, and select a region. Store the region domain in your application configuration and send your first message. After Adal returns 202 Accepted, the message will appear under Outbound → Messages for the selected region.
The complete authentication flow, request format, retry behavior, statuses, and current limits are covered in the Adal Outbound documentation.
Adal Outbound takes care of the delivery work that begins after an application creates an HTTP request: queueing, retries, and the diagnostics needed to understand every outcome. Your application creates the event and selects the recipient. Adal makes the rest of the delivery observable and predictable.