Twilio Messaging
Start agents with incoming SMS/MMS, WhatsApp, and RCS messages, and send replies, media, and approved templates through Twilio.
On this page
| Modes | Inbound, outbound |
| YAML type | twilio_messaging |
| Credentials | A Connection of type Twilio, shared with Twilio Voice |
| Bridge | Not supported |
| Custom domain | Not supported |
| Linked agents | One or more. An incoming message starts every linked agent; on outbound, each link sets how its agent sends. |
| While paused | Inbound: Twilio gets an empty TwiML response and no run starts. The message isn't stored or replayed. Outbound: nothing is sent. |
Set up
In Twilio, prepare the sender: a number with SMS or MMS, or a registered WhatsApp or RCS sender. For inbound, if a Messaging Service contains the sender, set the service's incoming-message handling to Defer to sender's webhook. To test WhatsApp without a registered sender, activate the Twilio Sandbox and join it from the test phone.
Open the agent. In Connector Flow, click Add inbound connector for inbound or Add outbound connector for outbound. Then click Create New Connector and select Twilio Messaging.
Choose the Mode. Under Connection, pick a Twilio Connection or create one with the region, Account SID, and that region's Auth Token. Select the Channel, then the Twilio sender. Senders the connector can't use, such as one another connic connector receives on, are listed but disabled, with the reason. For outbound, optionally set a Default recipient, Messaging Service SID, and template defaults. Click Create.
For inbound, connic sets the sender's incoming-message webhook in Twilio; see Provider setup. The WhatsApp Sandbox needs the webhook entered by hand. For outbound, choose how the agent sends: Automatic outbound connector, Agent-tool outbound connector, or Middleware outbound connector. For replies, choose Only selected inputs and select the inbound connector.
Send a message to the sender and open the run. For outbound, open the connector's run and look up the returned Message SID in Twilio's Messaging Logs.
In code
Declare the connectors in connectors/*.yaml. Quote phone numbers and IDs; unquoted, YAML reads a number such as +14155550123 as an integer and the deploy fails. An inbound connector that receives WhatsApp messages:
type: twilio_messaging
mode: inbound
connection: support-twilio
config:
channel: whatsapp
sender: "whatsapp:+14155550123"
agents:
- messaging-assistantAn outbound connector that replies from the same sender:
type: twilio_messaging
mode: outbound
connection: support-twilio
config:
channel: whatsapp
sender: "whatsapp:+14155550123"
agents:
- name: messaging-assistant
outbound: { usage: automatic, source: [support-whatsapp] } # replies to the inbound file's runsConfiguration
The fields of a Twilio Messaging connector, the same in connectors/*.yaml, the REST API, and connic MCP. The descriptions name the matching setting in the dashboard. Connectors in code describes the fields every connector shares, such as agents and environments.
| Field | Type | Status | Description |
|---|---|---|---|
| type | string | Required | twilio_messaging. |
| mode | string | Required | inbound or outbound. Dashboard: Mode. |
| connection | string | Required | Name or ID of a Twilio Connection, which holds the region, Account SID, and Auth Token. Dashboard: Connection. |
| config | object | Required | Twilio Messaging settings. |
| channel | string | Optional | Inbound and outbound. sms for SMS and MMS, whatsapp, or rcs. The Connection's region must support it; see Channels and regions. Dashboard: Channel.Default: sms |
| sender | string | Required | Inbound and outbound. The Twilio address the connector receives on or sends from: a quoted E.164 number such as "+14155550123" for SMS, the WhatsApp number with or without the whatsapp: prefix, or the RCS Sender ID such as rcs:brand_agent. The sender must exist in the Connection's account and region, except for the WhatsApp Sandbox, whatsapp:+14155238886. Dashboard: Twilio sender. |
| to | string | Optional | Outbound. Default recipient in the channel's address format. Leave it out to reply to incoming messages; see Recipients. Dashboard: Default recipient. |
| messaging_service_sid | string | Optional | Outbound. A Messaging Service that contains the sender: MG followed by 32 hex characters. connic sends it along with the sender. Dashboard: Messaging Service SID. |
| content_sid | string | Optional | Outbound. Default template: HX followed by 32 hex characters. While it is set, every message uses the template; see WhatsApp templates. Dashboard: Default Content Template SID. |
| content_variables | object | Optional | Outbound. Default template variables: string values keyed by variable number, such as {"1": "Alex"}. Quote keys and values. Needs content_sid. Dashboard: Default template variables, as JSON. |
Connection
A Twilio Connection holds the account credentials and can serve any number of Twilio Messaging and Twilio Voice connectors. The channel and sender belong to each connector. connic uses the credentials to list senders, set webhooks, and send messages, and the Auth Token to verify the signature of every request Twilio sends.
| Setting | Description |
|---|---|
| Region | US1 (United States), IE1 (Ireland), or AU1 (Australia). Defaults to US1. US1 supports every channel, IE1 supports SMS text only, and AU1 doesn't support Messaging. |
| Account SID | The Twilio account ID, starting with AC. The account must be active. |
| Auth Token | The Auth Token of the selected region, not an API key SID or secret. Twilio credentials are regional; see Manage Regional API Credentials. |
Generated values
connic sets these when the connector is created or its sender changes. Copy the webhook URL from the details drawer. Leave them out of YAML files; connic lint rejects them.
| Value | Modes | Description |
|---|---|---|
| Incoming-message webhook | Inbound | The URL Twilio posts incoming messages to. connic sets it on the sender, except for the WhatsApp Sandbox. |
sender_sid | Inbound | The sender's Twilio SID: PN for a number, XE for a WhatsApp or RCS sender. Not set for the WhatsApp Sandbox. |
Agent input
Modes: Inbound
Twilio sends each incoming message as a signed, form-encoded POST to the connector's webhook. connic checks it, queues a run for each linked agent, and answers with an empty TwiML response. Replies go out through a separate outbound connector. The run receives:
{
"message_sid": "SM00000000000000000000000000000001",
"channel": "whatsapp",
"from": "whatsapp:+14155550124",
"to": "whatsapp:+14155550123",
"text": "What is the status of order 12345?",
"conversation_id": "twilio_messaging:9e0f77d9-2fd8-5a8e-8d47-59fbf5b8a091",
"raw": {
"AccountSid": "AC00000000000000000000000000000000",
"MessageSid": "SM00000000000000000000000000000001",
"From": "whatsapp:+14155550124",
"To": "whatsapp:+14155550123",
"Body": "What is the status of order 12345?",
"NumMedia": "0"
}
}message_sidis the Twilio Message SID. A repeated webhook for the same message starts no second run for an agent.fromis the customer andtothe connector's sender, with thewhatsapp:orrcs:prefix on those channels.textis the message body. It is empty for a message with only media.rawholds every form field Twilio sent, including channel-specific fields.filesandfile_issuesappear when the message has attachments.
Attachments
connic downloads incoming media into files. Each file has name (the Twilio media SID with a file extension), mime_type, base64-encoded data, and size in bytes. A message takes up to 50 files, at most 32 MiB combined. Downloads need a US1 Connection.
An invalid or unavailable file is skipped on its own. At the first file over the count or size limit, connic keeps the files before it and omits that file and every later one. file_issues lists each omitted file with a code, a message, and the limit it hit, and the connector's logs record a warning. The run starts even when no file was accepted, unless Files required is on for the agent's link. The agent should check both files and file_issues.
Conversations
conversation_id stays the same for each combination of inbound connector, account, region, channel, sender, and customer. To keep the history across messages, set session.key to input.conversation_id and redeploy the agent; sessions aren't on by default. With an automatic outbound connector linked, the agent's plain-text result becomes the reply.
version: "1.0"
name: messaging-assistant
description: "Answers incoming Twilio messages"
model: connic/gpt-5.6-terra
system_prompt: |
Answer the incoming message clearly and briefly.
Ask for missing information before making assumptions.
Return the reply as plain text.
session:
key: input.conversation_id
ttl: 86400This example keeps a conversation for 86,400 seconds. See Agent YAML for the session settings.
Provider setup
Modes: Inbound
When you create an inbound connector, connic sets the sender's incoming-message webhook to the connector's webhook URL with HTTP POST. On a number, it also removes a Messaging TwiML App; on a WhatsApp or RCS sender, it keeps the fallback and status callback URLs. It doesn't change the number's voice settings. Outbound connectors change nothing in Twilio.
- connic refuses a sender whose webhook points to another connic connector, a number without SMS (or, in US1, MMS), and a sender in a Messaging Service that isn't set to Defer to sender's webhook.
- When you switch senders, connic sets the new sender's webhook and clears the old one if it still points to this connector.
- Deleting the connector clears the webhook if it still points to this connector. If connic can't clear it, the connector isn't deleted; check the sender in Twilio and try again.
WhatsApp Sandbox
Twilio offers no documented public API for the Sandbox webhook, so you set it yourself. Create the connector with the WhatsApp channel and the sender WhatsApp Sandbox (activation required), then copy the Incoming-message webhook from the details drawer. In Twilio's Sandbox settings, paste the exact URL into When a Message Comes in, select HTTP POST, and save; see Twilio's Sandbox webhook instructions. Change the Sandbox settings yourself when you switch the connector to another sender or delete it.
Channels and regions
The Twilio sender list shows the account's numbers with SMS or MMS, or its WhatsApp or RCS senders, depending on the channel. Each option shows the number's capabilities or the sender's status. RCS drafts stay selectable for testing; being listed doesn't mean a sender is approved for production. Follow Twilio's RCS testing and approval steps.
Click Refresh after adding or changing a sender in Twilio. A saved sender missing from the refreshed list stays as (current sender); check it in Twilio. Changing the Connection or channel clears the selected sender. The address formats apply to both modes:
| Channel | Twilio sender | Customer address | Region |
|---|---|---|---|
| SMS / MMS | +14155550123 | +14155550124 | US1; IE1 for SMS text only, without +1 numbers |
| whatsapp:+14155550123 | whatsapp:+14155550124 | US1 | |
| RCS | rcs:brand_xyz123_agent | rcs:+14155550124 | US1 |
Phone numbers use E.164 format with the leading + and country code. connic adds a missing whatsapp: or rcs: prefix. Route the number's incoming SMS to the selected region in Twilio before you create the connector; the region in connic doesn't change Twilio's routing. IE1 doesn't support +1 numbers as sender or recipient; see Messaging features in IE1. RCS messages go to an explicit rcs: recipient, so the connector doesn't fall back to SMS. See Twilio's RCS guide for sender setup.
Outbound delivery
Modes: Outbound
An outbound connector sends through Twilio's Messaging API from the configured sender, together with the Messaging Service SID when one is set. It sends when a linked agent's run completes, when the model calls it as a tool, or when middleware calls it, depending on the link's usage.
Automatic payload
An automatic link sends the run's final output. Plain text becomes the message text. A JSON object can carry the fields of the agent-tool payload below; its text can also be in body, message, response, or output.
Agent-tool and middleware payload
The model or middleware passes a JSON object with these fields. Unknown fields fail validation. A message needs text, media, or a template.
{
"text": "Your order has shipped.",
"to": "whatsapp:+14155550124",
"media_urls": ["https://example.com/shipping-label.png"]
}text: the message text, at most 1,600 characters. Optional for a message with only media.to: the recipient; see Recipients.media_urls: 1 to 10 public media URLs; see Media.content_sidandcontent_variables: a template and its variables; see WhatsApp templates.
Recipients
connic sends to the first recipient it finds:
toin the payload or the automatic output.- The connector's Default recipient.
- For a run started by an inbound Twilio Messaging connector, the customer who sent the message. Both connectors must use the same Connection, channel, and sender.
A default recipient takes precedence over replies; leave it empty to answer each customer. Sending fails when no recipient is found.
Media
Pass public HTTP or HTTPS URLs without embedded credentials in media_urls; Twilio fetches the files. A message takes up to 10 URLs for MMS and one for WhatsApp or RCS. IE1 sends text only. Outbound media uses URLs, not the base64 files format of incoming messages.
Each channel's file types and size limits apply. WhatsApp ignores text sent with audio, video, documents, or other non-image media, so send that text in a separate message. See Twilio's WhatsApp media behavior.
WhatsApp templates
Outside WhatsApp's 24-hour customer service window, send an approved template. Create the template and get it approved in Twilio, then set its Content SID and variables on the connector or in the payload. See Twilio's template guide.
{
"to": "whatsapp:+14155550124",
"content_sid": "HX00000000000000000000000000000000",
"content_variables": {"1": "12345", "2": "Friday"}
}Payload values override the connector's content_sid and content_variables. Variable values must be strings. A payload with content_sid can't also carry text or media_urls. While the connector has a default Content SID, every message uses the template: plain text from the agent is ignored and media URLs are rejected. Return content_variables to fill the template.
Delivery and retries
A successful connector run means Twilio accepted the request, not that the message was delivered. The run's output holds the Message SID and the status fields Twilio returned; check Twilio's Messaging Logs for the delivery status and channel errors.
connic retries connection failures before submission and 429 responses, waiting as long as Twilio's Retry-After asks, for 3 attempts in total. Other failures aren't retried. When the outcome is unknown, such as after a read or write failure or a 5xx response, check Twilio's logs before you resend; Twilio may already have accepted the message.
Limits and errors
| Limit | Value |
|---|---|
| Message text | 1,600 characters |
| Outbound media | 10 URLs for SMS/MMS, one for WhatsApp and RCS, none in IE1 |
| Incoming attachments | 50 files, at most 32 MiB combined; US1 only |
| Incoming request | 256 KiB of form data |
| Incoming messages | 1,000 per minute per connector |
| Delivery attempts | 3 in total for retryable failures |
| Active connectors | At the plan's active connector limit, creating a connector of either mode fails with 403 instead of creating it paused. A deploy that would create the connector or bring it back at the limit fails. |
On inbound, connic checks each request's X-Twilio-Signature against the generated webhook URL and the Auth Token, then the account, channel, and recipient, and answers Twilio with one of these statuses:
| Status | Meaning |
|---|---|
| 200 | Accepted. The response is an empty TwiML document. Paused connectors and connectors without linked agents also answer 200 and start no run. |
| 400 | The message is invalid, or the request is a delivery status callback. This URL only takes incoming messages. |
| 403 | The signature is invalid, or the account, channel, or recipient doesn't match the connector. Check the Connection's Auth Token and region, that the URL in Twilio is exactly the generated webhook, and that the connector's channel and sender match the message's To address. |
| 404 | No inbound Twilio Messaging connector exists at this URL. |
| 413 | The request is larger than 256 KiB. |
| 415 | The request isn't form-encoded. |
| 429 | The connector received more than 1,000 messages in a minute. |
| 503 | connic couldn't queue the message at that moment. |
| Problem | What to do |
|---|---|
| Creating the connector fails | Resolve the reported Twilio error. If the sender is connected to another connic connector, delete that connector first. If a Messaging Service contains the sender, select Defer to sender's webhook in the service and try again. |
| The Sandbox sends Twilio's demo reply | Enter the webhook URL in the Sandbox settings; see WhatsApp Sandbox. Resuming the connector in connic doesn't do this step. |
| No run starts | Check that the connector is active and linked to a deployed agent, that Twilio posts to the exact webhook URL with HTTP POST, and the sender's incoming-message settings in Twilio. |
| Attachments are missing | Read file_issues in the run input and the attachment warning in the connector's logs. Each issue names the omitted file and the reason. |
| Sending fails without a recipient | Set to, configure a default recipient, or make the inbound and outbound connectors use the same Connection, channel, and sender. |
| Twilio rejects the message | Check the Twilio error code, the sender's registration, the address format, the region, and the template's approval and variables. |
| No automatic reply | Check the agent's outbound link and its selected inputs, then the agent's result and the outbound connector's run. |