Skip to main content
connic

Twilio Messaging

By connic
InboundOutbound

Let an agent answer SMS, MMS, WhatsApp and RCS messages on your Twilio senders. Replies, media and approved WhatsApp templates go out through the same Twilio account.

Publisher
By connic
Modes
Inbound, Outbound
Set up in
Dashboard or connectors/*.yaml

Put an agent on the senders you already have

Pick a saved Twilio Connection, a channel and a sender. When you save an inbound connector, connic configures the sender's incoming-message webhook in Twilio for you.

One Connection for Voice and Messaging
The Connection holds your Account SID, the region and that region's Auth Token. Twilio Voice connectors can use the same Connection, and each connector keeps its own channel and sender.
Automatic webhook setup
connic registers the incoming-message webhook on save and replaces an existing webhook or Messaging TwiML App, with the previous values in the connector logs. If a Messaging Service contains the sender, set it to Defer to sender's webhook.
WhatsApp Sandbox
The Sandbox needs one manual step. Paste the connector's webhook URL into When a Message Comes in, choose HTTP POST and save.
Regions
US1 supports SMS/MMS, WhatsApp and RCS. IE1 supports SMS text without media or +1 numbers, and AU1 supports Voice only.
Channels and regions
ChannelTwilio senderCustomer addressRegion
SMS / MMS+4915112345678+4917612345678US1, IE1 (SMS text only)
WhatsAppwhatsapp:+4915112345678whatsapp:+4917612345678US1
RCSrcs:example_service_agentrcs:+4917612345678US1

Get every message verified and ready to read

Twilio signs each request. connic checks it, then starts every linked agent with the text, the sender details and any downloaded attachments.

Verified requests
connic validates X-Twilio-Signature with your Auth Token and checks the account, channel and recipient. A repeated webhook for the same Message SID maps to the same run.
Media as files
Attachments arrive in files, up to 10 per message and 10 MiB combined, and need a US1 Connection. Omitted files are listed in file_issues.
Conversation history
conversation_id identifies one customer on one sender. Set session.key to input.conversation_id, and follow-up messages share a session. Sessions are not enabled automatically.
input.json
{
  "message_sid": "SM3f9c2a7b8d1e4f60a5b7c9d2e4f6a8b1",
  "channel": "sms",
  "from": "+4917612345678",
  "to": "+4915112345678",
  "text": "Has order ord_8812 shipped yet?",
  "raw": {
    "MessageSid": "SM3f9c2a7b8d1e4f60a5b7c9d2e4f6a8b1",
    "From": "+4917612345678",
    "To": "+4915112345678",
    "Body": "Has order ord_8812 shipped yet?",
    "NumMedia": "0"
  },
  "conversation_id": "twilio_messaging:9e0f77d9-2fd8-5a8e-8d47-59fbf5b8a091"
}
agents/sms-support.yaml
session:
  key: input.conversation_id
  ttl: 86400

Reply to the customer or write first

Link an outbound connector with the same Connection, channel and sender. It sends after the run, when the agent calls it as a tool or when middleware calls it.

Recipient order
An explicit to comes first, then the connector's default recipient, then the customer who wrote in. Leave the default empty to reply to each customer.
Text and media
Send up to 1,600 characters of text and public media_urls that Twilio fetches, up to 10 for MMS and one for WhatsApp or RCS.
WhatsApp templates
Outside the 24-hour customer service window, send an approved template with its Content SID in content_sid and the values in content_variables. A template can't be combined with text or media_urls.
Delivery status
A completed outbound run means Twilio accepted the request. The run output holds the Message SID, so you can follow delivery in the Messaging Logs.
reply.json
{
  "text": "Here is how to swap the filter.",
  "to": "whatsapp:+4917612345678",
  "media_urls": ["https://example.com/guides/filter.png"]
}
template.json
{
  "to": "whatsapp:+4917612345678",
  "content_sid": "HX7d2c4e9a1b3f5d8c0e2a4b6c8d0f1e3a",
  "content_variables": { "1": "Jana", "2": "10:30" }
}

Declare both directions in code

Declare the inbound and the outbound connector as YAML files in connectors/. Both reference the Twilio Connection by name, so the files hold no credentials, and each deploy creates or updates them for its environment.

connectors/support-sms.yaml
type: twilio_messaging
mode: inbound
connection: support-twilio
config:
  channel: sms
  sender: "+4915112345678"
agents:
  - sms-support
connectors/support-sms-replies.yaml
type: twilio_messaging
mode: outbound
connection: support-twilio
config:
  channel: sms
  sender: "+4915112345678"
agents:
  - name: sms-support
    outbound: { usage: automatic, source: [support-sms] }

Where Twilio Messaging fits

Pick a setup to see what arrives from Twilio and what the agent sends back.

A customer sends a question with a photo, and the agent answers on WhatsApp through the linked outbound connector.

Customer on WhatsApp
Inbound Twilio Messaging
whatsapp-support
Reply on WhatsApp
input.json
{
  "message_sid": "MM5a1c3e7f9b2d4a6c8e0f1a3b5c7d9e2f",
  "channel": "whatsapp",
  "from": "whatsapp:+4917612345678",
  "to": "whatsapp:+4915112345678",
  "text": "The coffee machine shows this error. What should I do?",
  "raw": {
    "Body": "The coffee machine shows this error. What should I do?",
    "NumMedia": "1"
  },
  "conversation_id": "twilio_messaging:4c2a9e1b-7f3d-5b8e-a6c4-0d2f8e1a3b5c",
  "files": [
    {
      "name": "ME8b2d4f6a1c3e5b7d9f0a2c4e6b8d1f3a.jpg",
      "mime_type": "image/jpeg",
      "data": "<base64-bytes>",
      "size": 182344
    }
  ]
}
outbound-run-output.json
{
  "sid": "SM9e1d3b5f7a2c4e6b8d0f1a3c5e7b9d2a",
  "status": "queued",
  "to": "whatsapp:+4917612345678",
  "from": "whatsapp:+4915112345678",
  "error_code": null
}

A customer texts your number, and the agent answers from the same number with the order status.

Customer by SMS
Inbound Twilio Messaging
order-status
SMS reply from your number
input.json
{
  "message_sid": "SM3f9c2a7b8d1e4f60a5b7c9d2e4f6a8b1",
  "channel": "sms",
  "from": "+4917612345678",
  "to": "+4915112345678",
  "text": "Has order ord_8812 shipped yet?",
  "raw": { "Body": "Has order ord_8812 shipped yet?", "NumMedia": "0" },
  "conversation_id": "twilio_messaging:9e0f77d9-2fd8-5a8e-8d47-59fbf5b8a091"
}
outbound-run-output.json
{
  "sid": "SM6c8e0a2b4d6f8a1c3e5b7d9f0a2c4e6b",
  "status": "queued",
  "to": "+4917612345678",
  "from": "+4915112345678",
  "error_code": null
}

A daily schedule starts the agent, and it sends an approved WhatsApp template through an agent-tool outbound connector.

Daily schedule
Cron
appointment-reminders
WhatsApp template via Twilio
input.json
{
  "trigger": "cron",
  "schedule": "0 7 * * *",
  "triggered_at": "2026-10-14T07:00:00",
  "prompt": "Remind every customer who has an appointment tomorrow."
}
agent-tool-payload.json
{
  "to": "whatsapp:+4917612345678",
  "content_sid": "HX7d2c4e9a1b3f5d8c0e2a4b6c8d0f1e3a",
  "content_variables": { "1": "Jana", "2": "10:30" }
}

A customer asks how to replace a part, and the agent replies on RCS with the steps and a picture.

Customer on RCS
Inbound Twilio Messaging
repair-guide
RCS reply with an image
input.json
{
  "message_sid": "SM2b4d6f8a0c1e3a5c7e9b1d3f5a7c9e0b",
  "channel": "rcs",
  "from": "rcs:+4917612345678",
  "to": "rcs:example_service_agent",
  "text": "How do I replace the water filter?",
  "raw": { "Body": "How do I replace the water filter?", "NumMedia": "0" },
  "conversation_id": "twilio_messaging:8d3f1a5c-2e7b-5c9d-b1e3-6f0a2c4e8b7d"
}
agent-output.json
{
  "text": "Turn the old filter to the left and pull it out. See step 2.",
  "media_urls": ["https://example.com/guides/water-filter-step-2.png"]
}

Twilio Messaging FAQ

Yes. Twilio Voice and Twilio Messaging connectors use the same saved Connection with your Account SID, region and Auth Token. Each connector keeps its own channel and sender, and the region must support the channel. AU1 supports voice only.

Yes. Link an outbound connector to an agent that a schedule, a webhook or another connector starts, and set a default recipient or pass to with the message. On WhatsApp, a message outside the 24-hour customer service window needs an approved template.

Only with a session. Set session.key to input.conversation_id on the agent and redeploy it. Messages from the same customer to the same sender then share a session while it lasts.

Yes. Activate the Sandbox in Twilio and join it from the test phone. Select the WhatsApp Sandbox sender in connic, then paste the connector's webhook URL into When a Message Comes in in the Sandbox settings with HTTP POST. For production, use a registered WhatsApp sender.

It means Twilio accepted the request. Look up the Message SID from the run output in Twilio's Messaging Logs for the final status. When the outcome of a request is unknown, connic does not retry it, because a second request could send the message twice.