SMS via Twilio

Send and receive text messages through your agent using Twilio.


The SMS bridge connects your agent to Twilio for sending and receiving text messages. Inbound messages come in via a public webhook; outbound sends go through the local bridge service.

Requirements

  • A Twilio account — twilio.com (free trial available)
  • A Twilio phone number with SMS capability
  • Your server accessible at a public domain (required for the inbound webhook)

Trial Account Limitations

Twilio's free trial works for testing but has real restrictions:

  • You can only send SMS to verified phone numbers — you must verify each recipient's number in the Twilio console before they can receive a message from your trial account
  • Your outbound messages will be prefixed with "Sent from your Twilio trial account"
  • Trial accounts have a small credit balance (~$15) — enough for hundreds of test messages

To remove these restrictions, you'll need to upgrade to a paid account and, for US numbers used in outreach, complete A2P 10DLC registration (see below).


Step 1 — Create a Twilio Account

  1. Go to twilio.com and sign up
  2. Verify your email and phone number
  3. Twilio will ask what you're building — you can select "SMS" / "Notifications"

Step 2 — Get a Phone Number

  1. In the Twilio console, go to Phone Numbers → Manage → Buy a number
  2. Search for a number with SMS capability in your preferred area code
  3. Click Buy — US numbers cost about $1.15/month
  4. The number will appear in Phone Numbers → Manage → Active numbers

Step 3 — Find Your Credentials

  1. On the Twilio console home page (console.twilio.com), your Account SID and Auth Token are displayed in the "Account Info" section
  2. The Auth Token is hidden by default — click the eye icon to reveal it
  3. Copy both values — you'll add them to your server in the next step

Your phone number is the one you purchased in E.164 format (e.g., +12025551234).


Step 4 — Configure the Bridge

Add these to /opt/openclaw.env on your server:

TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token_here
TWILIO_PHONE_NUMBER=+12025551234

Then restart the bridge and verify it's running:

systemctl restart sms-bridge
curl http://localhost:3032/health

A healthy response looks like {"status":"ok"}.


Step 5 — Configure the Inbound Webhook

For the agent to receive replies, Twilio needs to know where to send inbound messages.

  1. In the Twilio console, go to Phone Numbers → Manage → Active numbers
  2. Click your phone number
  3. Scroll to the Messaging section
  4. Under A MESSAGE COMES IN, set:
    • Webhook URL: https://yourdomain.com/api/sms
    • HTTP method: HTTP POST
  5. Click Save

The Caddy config on your server exposes this route:

handle /api/sms {
    reverse_proxy localhost:3032
}

To test the webhook is reachable from Twilio, send a text to your Twilio number and check:

curl http://localhost:3032/sms/inbox

You should see the inbound message in the response.


A2P 10DLC (US Numbers — Outreach Use)

If you're in the US and plan to send SMS to people who haven't texted you first (i.e., outreach), you're required by US carriers to register under A2P 10DLC (Application-to-Person, 10-digit long code). Without registration, messages may be filtered or blocked by carriers.

Registration happens in the Twilio console under Messaging → Regulatory Compliance. You'll need:

  • A business name and address
  • EIN (for US businesses) or equivalent
  • A description of your messaging use case

Registration costs ~$4 one-time and takes 1–3 business days for approval. For personal/low-volume use where the recipient has already opted in, you may be able to skip this initially — but be aware carriers may filter unregistered traffic.


Bridge API Reference

The bridge runs on localhost:3032. Only the /api/sms webhook path is publicly accessible via Caddy.

POST /sms/send          { to, body }
GET  /sms/inbox         { since? }    — returns inbound messages (in-memory, last 100)
POST /sms/webhook       (Twilio calls this for inbound messages)

GET  /health

Note: The inbox is in-memory — it resets on service restart. For persistent inbound storage, add SQLite logging to the bridge service.


Safety Notes

  • Never expose /sms/send publicly — it must stay local-only
  • Require explicit approval before the agent sends its first message to any new contact
  • All outbound sends are logged with timestamp, recipient, and content
  • Set a per-day send limit before enabling autonomous outreach

Verifying Everything Works

Send a test message from the agent:

curl -s -X POST http://localhost:3032/sms/send \
  -H "Content-Type: application/json" \
  -d '{"to":"+15551234567","body":"Test from the SMS bridge"}'

Check that it arrived. Then text a reply back to your Twilio number and confirm it shows up in the inbox:

curl http://localhost:3032/sms/inbox