ZuloOne
English
Sign in
Menu

Send an outbound call

Updated

A script talks to a tax office, a bank, or an operator by channel name. The host owns the wire, the address, and the secret. HttpClient is outside the script reference set.

Note

Never open a socket from a script. Name the channel. The host resolves URL, credential, signature, and SSRF. ICredentialResolver is on the deny-list — What a script can do.

How to#

1. A channel — OutboundChannels/<name>.channel.json in your model, kind OutboundChannel. Path, method, signer, authMode, content type. The tenant's live address and timeout live on the connection dictionary named in connectionTable, not in the channel. Secrets never go in the workspace.

2. Pick the door. The choice is not style.

IOutboundGateway IOutboundCall
What a queue (outbox) a synchronous call
When a document must be sent an exchange needs its response now
Retry yes no

If losing the message means losing the document, enqueue. If the response is single-use (an OTP swapped for a CSID), IOutboundCall — a queue row would log the secret and a retry would present a spent OTP.

await ScriptServices.Get<IOutboundGateway>().EnqueueAsync(new OutboundRequest
{
    Channel = "fatoora-clearance",
    IdempotencyKey = "zatca:" + uuid.ToString("N"),
    Payload = body,
    SourceTable = "TaxDocument",
    SourceRecordId = envelope.MetaId,
});

var result = await ScriptServices.Get<IOutboundCall>().SendAsync(
    "fatoora-compliance", payload, idempotencyKey: "zatca-compliance");

Both take a channel name, not a URL.

3. Bump modelVersion. A new channel also needs POST /api/services/rebuild.

Warning

A successful send is not a receipt. Ask the country contour: is the response the authority's decision, or an operator's "accepted for processing"? Closing the envelope on Succeeded when a receipt still has to be fetched registers documents the authority has not seen.

InDoubt means the request left and no answer came back. The document may already be registered. Do not retry that status. Query fate; do not submit again.

There is no inbound callback. Drain your own outbox for send outcomes; poll the other side with IOutboundCall when you need a receipt.

The longer page is Outbound integrations — signing profiles, four guards against a second submit, and how a country package writes the outcome.

What's not there yet#

The platform does not accept an inbound call from outside. CompletionHandler is reserved and unread. An integration test cannot cover the exchange itself: cover everything before the send and everything after the response; say so in the test header.

Where next#

Was this page helpful?