Docs

Reach · 08.03

Deterministic Channel Sends

A workflow reaches the world with a zero-token channel node — not an agent prompt — that resolves a connection, delivers, and returns a receipt SWIFT can verify.

ChannelsWorkflows

A message contract sends nothing — a channel node does

There are two ways to send on a channel, and conflating them is the classic reachability bug. agentis.channel.send is the tool an agent calls mid-conversation. But a deterministic, zero-token workflow — a "send the first-contact greeting" pipeline — must not spin up an LLM just to deliver a string. For that there is a first-class channel node: { kind: "channel", channelKind: "whatsapp", to, body }. A workflow that only computes a recipient and message in a transform sends nothing; the node is what actually reaches the world, and if it can't, it fails the run loudly rather than reporting a hollow success.

How the node picks a connection

GivenResolves to
An explicit connectionIdThat exact connection.
Just channelKind (e.g. "whatsapp")The workspace default connection for that kind — or the sole active one if there's only one.
A kind with several connections and no defaultA clear error asking you to set a default or pass a connectionId — never a silent guess.

This is why a connection's owner and its send target are orthogonal. A connection is a transport; its owning agent governs inbound routing and conversational identity, not a lock on outbound. A workspace-owned connection (no owning agent — connected globally in Settings → Channels) is a shared resource any workflow or agent can send on; a agent-owned one carries that agent's identity and is gated by per-agent grants. Designate one connection per kind as the default and deterministic automation resolves it unambiguously, even when you run two numbers.

The receipt makes the send provable

On success the node stores a delivery receipt — the connection it used, the resolved destination, and a timestamp — so the SWIFT verdict engine has real evidence a message went out, not a self-reported "sent ✓". A dry run never delivers: the node is mocked like any other side-effecting step, so testing a workflow can't fire a real WhatsApp message.

Continue