Twilio Console Configuration¶
Step-by-step guide for configuring your Twilio phone number to work with omni-twilio.
Prerequisites¶
- A Twilio account
- A Twilio phone number
- Your application running with a public URL (or ngrok for development)
Finding Your Credentials¶
- Log in to Twilio Console
- On the dashboard, locate:
- Account SID: Starts with
AC -
Auth Token: Click the eye icon to reveal
-
Set as environment variables:
export TWILIO_ACCOUNT_SID="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export TWILIO_AUTH_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Phone Number Configuration¶
Navigate to Your Phone Number¶
- Go to Phone Numbers → Manage → Active numbers
- Click on the phone number you want to configure
Voice Configuration¶
Scroll to the Voice Configuration section:
| Field | Value | Description |
|---|---|---|
| Configure with | Webhooks | Use webhook URLs |
| A call comes in | https://your-server.com/voice/inbound |
Incoming call handler |
| HTTP Method | POST | Required method |
| Primary handler fails | (optional) | Fallback URL |
| Call status changes | https://your-server.com/voice/status |
Status updates |
Click Save configuration.
Messaging Configuration¶
Scroll to the Messaging Configuration section:
| Field | Value | Description |
|---|---|---|
| Configure with | Webhooks | Use webhook URLs |
| A message comes in | https://your-server.com/webhook/twilio/sms |
Incoming SMS/MMS |
| HTTP Method | POST | Required method |
| Primary handler fails | (optional) | Fallback URL |
Click Save configuration.
Voice Gateway Setup¶
The voice gateway supports two pipeline modes. See the Voice Gateway Guide for detailed configuration.
Webhook URLs¶
Configure these URLs in Twilio Console:
| Webhook | Path | Purpose |
|---|---|---|
| Voice URL | /voice/inbound |
Handles incoming calls |
| Status Callback | /voice/status |
Call status updates |
Pipeline Modes¶
| Mode | Latency | Best For |
|---|---|---|
| Text | 500-1000ms | Custom voices, domain-specific STT, tool calling |
| Realtime | 100-200ms | Natural conversation, low latency requirements |
Text Mode Example¶
import "github.com/plexusone/omni-twilio/omnivoice/gateway"
gw, err := gateway.New(gateway.Config{
AccountSID: os.Getenv("TWILIO_ACCOUNT_SID"),
AuthToken: os.Getenv("TWILIO_AUTH_TOKEN"),
PhoneNumber: "+15551234567",
PublicURL: "https://your-server.com",
ListenAddr: ":8080",
// Text mode: STT → LLM → TTS
STTProvider: "deepgram",
LLMProvider: "anthropic",
LLMModel: "claude-sonnet-4-20250514",
LLMSystemPrompt: "You are a helpful voice assistant.",
TTSProvider: "elevenlabs",
})
gw.Start(ctx)
Realtime Mode Example¶
import (
"github.com/plexusone/omni-twilio/omnivoice/gateway"
coregateway "github.com/plexusone/omnivoice-core/gateway"
openaiRealtime "github.com/plexusone/omni-openai/omnivoice/realtime"
)
gw, err := gateway.New(gateway.Config{
AccountSID: os.Getenv("TWILIO_ACCOUNT_SID"),
AuthToken: os.Getenv("TWILIO_AUTH_TOKEN"),
PhoneNumber: "+15551234567",
PublicURL: "https://your-server.com",
ListenAddr: ":8080",
// Realtime mode: ~100ms latency
Mode: coregateway.PipelineModeRealtime,
RealtimeProvider: openaiRealtime.NewFactory(),
RealtimeConfig: &coregateway.RealtimeConfig{
Provider: "openai",
APIKey: os.Getenv("OPENAI_API_KEY"),
Model: "gpt-4o-realtime-preview-2024-12-17",
Voice: "alloy",
Instructions: "You are a helpful voice assistant.",
},
})
gw.Start(ctx)
SMS/MMS Setup¶
Webhook URLs¶
Configure this URL in Twilio Console:
| Webhook | Path | Purpose |
|---|---|---|
| Message URL | /webhook/twilio/sms |
Incoming SMS/MMS |
Code Example¶
import "github.com/plexusone/omni-twilio/omnichat"
provider, err := omnichat.New(
omnichat.WithAccountSID(os.Getenv("TWILIO_ACCOUNT_SID")),
omnichat.WithAuthToken(os.Getenv("TWILIO_AUTH_TOKEN")),
omnichat.WithPhoneNumber("+15551234567"),
)
// Connect provider
provider.Connect(ctx)
// Mount webhook handler
http.Handle("/webhook/twilio/sms", provider.WebhookHandler())
// Handle incoming messages
provider.OnMessage(func(ctx context.Context, msg provider.IncomingMessage) error {
fmt.Printf("From: %s, Body: %s\n", msg.SenderID, msg.Content)
// Handle MMS attachments
for _, media := range msg.Media {
fmt.Printf("Media: %s (%s)\n", media.URL, media.MimeType)
}
return nil
})
RCS Setup (Rich Communication Services)¶
RCS enables rich messaging with branded senders, rich cards, and suggested actions.
Step 1: Create a Messaging Service¶
- Go to Messaging → Services
- Click Create Messaging Service
- Name it (e.g., "My App RCS")
- Click Create
Step 2: Add Phone Number to Sender Pool¶
- In your Messaging Service, click Sender Pool
- Click Add Senders → Phone Numbers
- Select your phone number
- Click Add Phone Numbers
Step 3: Add RCS Sender (Optional)¶
- Click Add Senders → RCS Sender
- Complete the RCS onboarding (requires carrier approval)
Step 4: Get Messaging Service SID¶
- Go to your Messaging Service overview
- Copy the Messaging Service SID (starts with
MG)
Step 5: Configure Environment¶
Code Example¶
import "github.com/plexusone/omni-twilio/omnichat"
provider, err := omnichat.New(
omnichat.WithAccountSID(os.Getenv("TWILIO_ACCOUNT_SID")),
omnichat.WithAuthToken(os.Getenv("TWILIO_AUTH_TOKEN")),
omnichat.WithMessagingServiceSid(os.Getenv("TWILIO_MESSAGING_SERVICE_SID")),
)
// Messages sent via RCS with automatic SMS/MMS fallback
provider.Send(ctx, "+15559876543", provider.OutgoingMessage{
Content: "Hello via RCS!",
})
// Send with content template (rich cards)
provider.Send(ctx, "+15559876543", provider.OutgoingMessage{
Content: "Order update",
Metadata: map[string]any{
"content_sid": "HXxxxxxxxx",
"content_variables": `{"1": "John", "2": "#12345"}`,
},
})
Local Development with ngrok¶
Install and Configure ngrok¶
- Sign up at ngrok.com
- Install ngrok:
- Authenticate:
Start ngrok Tunnel¶
ngrok will display a URL like:
Update Twilio Webhooks¶
- Copy the ngrok HTTPS URL
- Go to Phone Numbers → Active numbers → your number
- Update webhook URLs:
- Voice:
https://abc123.ngrok.io/voice/inbound - SMS:
https://abc123.ngrok.io/webhook/twilio/sms - Click Save configuration
URL Changes on Restart
Free ngrok URLs change every time you restart ngrok. Update Twilio webhooks accordingly, or use a paid ngrok plan for persistent URLs.
Testing Your Setup¶
Test Voice¶
- Call your Twilio phone number
- Check your server logs for incoming call events
- Verify the call connects and TwiML is served
Test SMS¶
- Send an SMS to your Twilio phone number
- Check your server logs for incoming message
- Verify the webhook handler receives the message
Test via Twilio Console¶
- Go to Phone Numbers → Active numbers → your number
- Under Voice, click Make a test call
- Under Messaging, use the Send a test message feature
Debugging¶
Twilio Debugger¶
- Go to Monitor → Logs → Errors
- Click on errors to see request/response details
Common Issues¶
| Issue | Cause | Solution |
|---|---|---|
| 11200 HTTP retrieval failure | Webhook URL not accessible | Check URL is public, HTTPS valid |
| 11205 Connection failure | Server not running | Start your server |
| 12100 Document parse failure | Invalid TwiML response | Check response format |
| No webhook received | Wrong URL configured | Verify URL in Console |
Enable Request Logging¶
import "log/slog"
provider, err := omnichat.New(
omnichat.WithAccountSID("..."),
omnichat.WithAuthToken("..."),
omnichat.WithLogger(slog.Default()), // Enable logging
)
Security¶
Validate Webhook Signatures¶
omni-twilio validates webhook signatures automatically when the Auth Token is configured. This ensures requests come from Twilio.
Use HTTPS¶
Twilio requires HTTPS for all webhook URLs. ngrok provides this automatically for local development.
Protect Auth Token¶
Never commit your Auth Token to version control:
Environment Variables Reference¶
| Variable | Description | Required |
|---|---|---|
TWILIO_ACCOUNT_SID |
Account SID (starts with AC) | Yes |
TWILIO_AUTH_TOKEN |
Auth Token | Yes |
TWILIO_PHONE_NUMBER |
Phone number (E.164 format) | For outbound |
TWILIO_MESSAGING_SERVICE_SID |
Messaging Service SID for RCS | For RCS |
Next Steps¶
- Voice Gateway Guide - Full-duplex voice calls with text and realtime modes
- OmniChat Provider - SMS/MMS integration