Back to documentation

Sending through the Outbound API

Authorization, region selection, the HTTP job JSON envelope, acceptance response and execution results.

View as Markdown
On this page

When to use Outbound

Outbound executes HTTP jobs submitted by your application through the Adal API. No incoming Server, Channel or Router is required. Each submission specifies its recipient and region. To forward an accepted webhook, use Inbound Direct, not this API.

Submission flow

Application → Adal API → selected region → HTTP recipient. Execution is asynchronous: the API accepts a job, while its outcome and attempts are read separately. The submission response does not synchronously return the recipient's response body.

Authorization

Create an API token and send it to https://api.adal.cloud:

Authorization: Bearer <API-token>

The public API base URL is https://api.adal.cloud. In the examples, set ADAL_API_URL to this value without a trailing slash. Public service connections use HTTPS and WSS.

Session refresh

Use an API token for application requests; signing in to the dashboard does not authorize your application. When an API token expires, issue and configure a replacement.

Which token to send

Use the account API token's secret, not a Channel CLI token, password or dashboard sign-in credentials. The Outbound dashboard uses its own session; viewing its journal does not require pasting an API token.

Region

GET /outbound/regions with an API token returns regions with the case-sensitive fields ID, Code, Name, Country, City. Select an actual ID and pass it as region_id. The recipient URL does not select a region automatically, and an accepted job does not change region. See Regions.

Submit a job

Use POST /outbound/requests with Content-Type: application/json. This API path does not accept query parameters. The body is one JSON object; unknown or repeated fields and incorrect types are rejected.

Job fields

Field Requirement
region_id Required region catalog UUID in canonical lowercase form
method Required valid HTTP method
url Required full HTTP/HTTPS recipient URL; query is allowed, userinfo and fragment are not
headers Required object mapping header names to string arrays; {} for no headers
body Required standard base64 string; "" for an empty body
idempotency_key Optional nonempty key identifying one logical operation
save_response_body Optional boolean, default false

Send only the submission fields listed above; request identifiers and acceptance times are assigned for you. Do not use null for required values. Unlike an Inbound Endpoint base URL, Outbound accepts the full final URL and does not append a Server path.

Headers

For example, "headers":{"Content-Type":["text/plain"],"X-Demo":["first","second"]}. Values are arrays, not single strings. Line breaks in values are forbidden. Transport headers, Host and Content-Length are formed for a new connection; client service headers may also be replaced. Do not expect byte-for-byte equivalence of the entire network packet.

Idempotency key

Identical calls without a key are not automatically deduplicated. Choose and save a key explicitly, and reuse it only for the same logical submission. Use a new key for a new operation. Checking is scoped to the account and retention period; after expiry the key no longer prevents new execution.

A submission key does not automatically set an Idempotency-Key HTTP header at the recipient. If your handler needs that header, supply it explicitly and implement application-side deduplication.

Body

aGVsbG8= is standard base64 for the bytes hello. Do not send a nested JSON object as body: serialize your data to bytes, then encode it. URL-safe base64 is not a substitute for standard base64. Usage counts decoded bytes, not the base64 string length.

Acceptance response

Success is 202 with request_id and received_at. It confirms acceptance, not HTTP success. Save the identifier and read the journal; a record may not appear immediately. A lost response or 503 can leave acceptance uncertain: retry using the same key rather than creating a new logical operation.

Statuses

received, delivering, success, failed, rejected and duplicate describe different stages and outcomes. HTTP data expiry is a separate flag, not a seventh status. See the journal for meanings, filters and duplicate_of.

Attempts

The executor makes automatic attempts until success or completion under execution rules. A 2xx without an error and with response reading completed correctly is HTTP success; it does not establish a business result. Redirects are not followed automatically. See the shared retry rules.

Repeated effects

A recipient can perform an action before its response is lost. Another HTTP attempt can repeat it even for one accepted job. Submission idempotency and external-effect idempotency are different responsibilities; the service does not promise exactly-once execution.

Recipient security

Use a final URL under your control and do not send the Adal API token to the recipient. The executor checks local, private and service destinations; 202 does not mean the URL is allowed and reachable for execution. HTTPS certificates and reachability are checked when connecting.

History and diagnostics

Open Outbound → Requests in the dashboard. Through the API, read the journal and card by request_id. See diagnostics for attempts, wait reasons, network/TLS/HTTP details and snapshot changes, and HTTP data for bodies.

Region and retention

HTTP data is stored in the selected region. A visible journal record does not mean that its content is still available. Expired content cannot be recovered from the remaining journal row. Retries and reads do not extend retention. See Storage.

Usage

The decoded original body is counted once when the first attempt starts. Responses are not stored by default; with save_response_body=true, stored responses from each attempt are added, including failed and incomplete ones. See Traffic.

Errors

Response Check
400 invalid_request JSON, fields, UUID, URL, header arrays and base64; this is validation failure, not a job's rejected status
401 Correct API token, expiration and revocation
413 payload_too_large Body, envelope and metadata size; the request was not published
503 unavailable Temporary failure or uncertain acceptance; preserve the key when retrying

Result-read errors 404, 409 and 410 have other meanings; do not replace a read with another POST. Follow the journal, diagnostics and body guides.

Boundaries

Bodies, JSON envelopes, metadata, details and downloads have separate constraints. Base64 increases the body size inside JSON: acceptable original bytes do not by themselves establish that the entire envelope fits. The URL and headers also contribute to metadata size. A traffic package does not remove technical limits.

For 413 payload_too_large, check the original body, entire JSON and metadata sizes; reduce the data sent and remove unnecessary headers. Repeating the unchanged request does not resolve the excess. Invalid format, including an invalid idempotency_key, is a 400 invalid_request issue rather than a size-limit error.

Do not rely on strict ordering, fixed execution time, manual dashboard replay or automatic regional failover.

Complete integration flow

Create an API token → list regions → save an operation key → submit → save the ID → read outcome and attempts → optionally load details and bodies. For uncertain submission, retry the same request with the same key; for a failed read, retry reading.

API paths

Method and path Purpose
GET /outbound/regions Available regions
POST /outbound/requests Accept a job
GET /outbound/requests Journal
GET /outbound/requests/{request_id} Card
GET /outbound/requests/{request_id}/http HTTP data summary
GET /outbound/requests/{request_id}/http/details Details page for one revision
GET /outbound/requests/{request_id}/body Original request bytes
GET /outbound/requests/{request_id}/attempts/{attempt_id}/response/body Stored attempt response bytes

Quickstart, journal, diagnostics, HTTP data.

Related documentation