Skip to main content
Channels sends messages to end users on the channels the agent is connected to and reads the delivery record each send creates. A send addressed to a person is recorded in that person’s conversation with the agent, so the agent has the context when they reply. Available in tools, jobs, webhooks, triggers, processors, and workflow code steps. For the rules per channel, including the WhatsApp 24-hour window, see Send proactive messages. Verified against lua-cli 3.33.0.

Quick example

A send returns a delivery id; getStatus reads the receipts that arrive later.

Methods

send(input)

Sends a text message on one channel.
ChannelSendChannel
required
One of CHANNEL_SEND_CHANNELS: whatsapp, sms, email, webchat, teams, instagram, messenger. These are outbound ids; the inbound value in Lua.request.channel is pop for the widget (the Channel type spells it web) and facebook for Messenger.
ChannelSendTarget
required
Exactly one of userId (any channel), phoneNumber (whatsapp and sms, E.164), email (email), or conversationId (teams only: a group chat or channel the agent is already in; everyone in it receives the message). teams, instagram, and messenger need a prior inbound conversation, so they accept userId or conversationId only; webchat accepts userId only.
string
required
The message. ::: formatting components render the way they do in replies.
string
Pins the send to one channel configuration when the agent has several of the same type. It must belong to the agent.
'queue' | 'fail'
default:"queue"
What to do when the WhatsApp 24-hour window is closed. queue sends the platform’s message-request template, holds the text, and delivers it when the end user replies; fail rejects the send so you can send your own approved WhatsApp message template with whatsapp.sendTemplate.
Returns
ChannelSendOutput
Example
Errors — the call throws when the send is rejected. In a deployed agent the error is a ChannelSendError with code and statusCode; in lua test it is a plain Error carrying the server’s message, or Channel send failed.
  • Unknown channel: <channel>
  • to must have exactly one of userId, phoneNumber, email, or conversationId
  • conversationId is only supported on teams
  • <channel> is a warm-only channel; address by userId or conversationId
  • webchat channel requires to.userId
  • phoneNumber cold-start not valid for <channel>; use userId
  • A closed WhatsApp window with onClosedWindow: 'fail', or a provider rejection.

whatsapp.sendTemplate(input)

Sends an approved WhatsApp message template to one person, inside or outside the 24-hour window.
{ userId?: string; phoneNumber?: string }
required
Exactly one of userId or phoneNumber (E.164).
string
required
The name of an approved WhatsApp message template on the agent’s WhatsApp channel. List them with Templates.whatsapp.list.
string
The template’s language, for example en_US.
Array<Record<string, unknown>>
Meta component objects with the parameter values, for example { type: 'body', parameters: [{ type: 'text', text: 'ORD-99' }] }.
string
Plain text recorded in the conversation as what the template said, so the agent remembers the outreach. Recommended whenever the template body isn’t self-explanatory.
ChannelSendOptions
As on send.
Returns — a ChannelSendOutput. Example
Errorsto must provide userId or phoneNumber, phoneNumber must contain digits, a template that isn’t approved, or a provider rejection; thrown as on send.

whatsapp.sendReaction(input)

Reacts to a WhatsApp message with one emoji, the way a person does by long-pressing it.
{ userId?: string; phoneNumber?: string }
required
Exactly one of userId or phoneNumber (E.164).
string
required
The provider id of the message to react to, a wamid… value from the conversation history or the channel payload. Meta accepts messages up to 30 days old.
string
required
One emoji. An empty string removes the agent’s existing reaction.
ChannelSendOptions
As on send.
Returns — a ChannelSendOutput. Example
ErrorsmessageId is required, emoji is required (an empty string removes the reaction), to must provide userId or phoneNumber; thrown as on send.

email.send(input)

Sends an email with a subject, a plain-text, HTML, or rendered body, copies, attachments, and threading headers. The agent must have an email channel linked.
{ userId?: string; email?: string }
required
One of userId (resolved to the address from the end user’s history) or email.
string
The subject line.
string
Plain-text body, sent as is. Provide one of text, html, or richBody.
string
Exact HTML body, sent as is with no template around it.
string
Markdown and ::: components, rendered on the server into the branded email template that the agent’s own replies use.
string[]
Copy recipients.
string[]
Blind-copy recipients.
Array<{ filename: string; contentType: string; url: string }>
Files fetched from url at send time and attached. The combined size is limited to 28 MB.
string
The Message-ID of the email this one answers; sets In-Reply-To so mail clients thread it. The inbound email’s id is Lua.request.webhook.payload.messageId. Angle brackets are optional. Honored on the branded (existing-address) email channel.
string[]
The thread’s accumulated Message-IDs for the References header.
ChannelSendOptions
As on send.
Returns — a ChannelSendOutput; messageId is the provider’s message id. Example
ErrorsNo email channel configuration found. Ensure the agent has an email channel linked. when the agent has no email channel, email send requires to.email or to.userId, email send requires a text, html, or richBody body, Attachments exceed the 28MB limit; thrown as on send.

getStatus(deliveryId)

Reads one delivery record, including receipts that arrived after the send.
string
required
The id a send returned.
Returns — a DeliveryView. status only moves forward through queued, accepted, sent, delivered, read; failed is terminal and carries error; expired is a queued WhatsApp message the end user never replied to. A late or duplicate receipt leaves the record where it is, so polling is safe. Example
Errors — throws when no delivery with that id belongs to the agent.

listDeliveries(filter?)

Lists the agent’s deliveries, newest first.
string
Only deliveries addressed to this end user.
DeliveryStatus
Only deliveries in this status.
string
A channel name such as whatsapp, email, or sms.
string | Date
Only deliveries created at or after this instant.
number
default:50
From 1 to 200.
Returns — an array of DeliveryView. Example
ErrorsDelivery list failed when the platform gives no message.

Retries and idempotency

Every send endpoint accepts an X-Idempotency-Key header. In lua test the SDK adds a fresh key to each Channels call, so a transport retry inside one call can’t send twice. In a deployed agent the call is made in process with no key, so a retry of your own, such as a job that runs again after crashing, sends again. To deduplicate across runs, call the REST send endpoints with a key you derive from the thing you are messaging about. Replaying a key returns the first send’s outcome with the same deliveryId for the life of the delivery record, 180 days; a key whose first attempt failed replays the failure; keys are scoped to one agent.

Types

readonly string[]
['whatsapp', 'sms', 'email', 'webchat', 'teams', 'instagram', 'messenger']. ChannelSendChannel is its element type.
interface
channel, to, text, options?, as on send. ChannelSendTarget and ChannelSendOptions are the shapes of to and options.
interface
The send result described under send.
interface
The inputs of whatsapp.sendTemplate, whatsapp.sendReaction, and email.send.
interface
The filter of listDeliveries.
union
queued (WhatsApp, held until the end user replies), accepted (the provider took it and returned an id), sent (handed to the recipient’s network; where a channel has no receipts, a successful send stops here), delivered, read (WhatsApp, with read receipts on), failed, expired.
interface
interface
category (a DeliveryErrorCategory), provider, code (the vendor’s own code, as a string), title, detail?, href? (a remediation link), retryable, and owner (customer, recipient, lua, or vendor: who has to act).
union
The same vocabulary for every provider.

See also

  • Send proactive messages — windows, WhatsApp message templates, and when to use User.send
  • Templates — list WhatsApp message templates and batch-send by phone number
  • Team — resolve a colleague’s shared handles before sending
  • REST channels API — the same sends with X-Idempotency-Key
  • About channels — the inbound and outbound channel vocabularies