Skip to main content

Twilio SMS Connector

Send and receive SMS (and optional MMS with media attachments) via Twilio's Programmable SMS API.

Package

dotnet add package Ratatosk.Twilio

Required settings

ParameterTypeDescription
AccountSidstringTwilio account SID (starts with AC)
AuthTokenstringTwilio auth token (sensitive)

Optional settings

ParameterTypeDefaultDescription
MessagingServiceSidstringTwilio Messaging Service SID for advanced routing
WebhookUrlstringURL for inbound SMS and status callbacks
StatusCallbackstringURL for delivery status callbacks
ValidityPeriodintMessage validity in seconds (14400 = 4 hours default)
MaxPricedecimalMaximum price per message
SmartEncodedboolOptimize for GSM-7 charset

Schema

PropertyValue
ProviderTwilio
TypeSMS
Version1.0.0
CapabilitiesSendMessages, MessageStatusQuery
Content typesPlainText, Media
EndpointsPhoneNumber (send + receive)
AuthenticationBasic (AccountSid + AuthToken)
Parameters2 required, 5 optional

Send examples

Text SMS

var settings = new ConnectionSettings()
.SetParameter("AccountSid", "AC...")
.SetParameter("AuthToken", "...");

var connector = new TwilioSmsConnector(TwilioChannelSchemas.SimpleSms, settings);
await connector.InitializeAsync(ct);

var message = new MessageBuilder()
.WithId("sms-1")
.FromPhone("+15550001111")
.ToPhone("+15550002222")
.WithText("Hello from Twilio SMS")
.Build();

var result = await connector.SendMessageAsync(message, ct);

if (result.IsSuccess)
{
Console.WriteLine($"Sent! Twilio SID: {result.Data?.RemoteMessageId}");
Console.WriteLine($"Status: {result.Data?.Status}");
}

SMS with media (MMS)

var message = new MessageBuilder()
.WithId("mms-1")
.FromPhone("+15550001111")
.ToPhone("+15550002222")
.WithContent(new MediaContent(MediaType.Image, "photo.jpg",
"https://example.com/photo.jpg"))
.Build();

SMS with custom validity

new MessageBuilder()
.FromPhone("+15550001111")
.ToPhone("+15550002222")
.WithText("Time-sensitive message")
.WithValidityPeriod(300) // 5 minutes
.WithMaxPrice(0.01) // $0.01 max
.Build();

Message properties

PropertyTypeDescription
ValidityPeriodintTime in seconds the message is valid
MaxPricedecimalMaximum price to pay for the message
ProvideCallbackboolRequest a delivery callback
SmartEncodedboolOptimize for GSM-7 charset

Webhook handling

Twilio sends inbound messages and status callbacks as form POST requests. The MessageSource.UrlPost() factory handles parsing:

[HttpPost("/webhooks/twilio/sms")]
public async Task<IActionResult> TwilioWebhook(CancellationToken ct)
{
// Read the raw form body into a MessageSource
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadToEndAsync();
var source = MessageSource.UrlPost(body);

// Process the status update
var statusResult = await _connector.ReceiveMessageStatusAsync(source, ct);

// Or process an inbound message
var messageResult = await _connector.ReceiveMessagesAsync(source, ct);

return TwiML.Empty; // Return TwiML response
}

Important: validate X-Twilio-Signature before processing. See Twilio security docs.

Error codes

Twilio-specific error codes are defined in TwilioErrorCodes with domain "Twilio".

CodeDescription
INVALID_CONNECTION_SETTINGSConnection settings validation failed
MISSING_FROM_NUMBERSender phone number is required when MessagingServiceSid is not configured
INVALID_SENDERSender phone number is not in valid format
INVALID_MESSAGEMessage properties failed schema validation
MISSING_CONTENT_SIDWhatsApp template Content SID is missing
INVALID_WHATSAPP_NUMBERWhatsApp number does not follow whatsapp:+E164 format
SEND_WHATSAPP_MESSAGE_FAILEDWhatsApp message send failed via Twilio API
WHATSAPP_STATUS_QUERY_FAILEDWhatsApp message status query failed
STATUS_QUERY_FAILEDMessage status query failed
STATUS_ERRORConnector status retrieval failed
RECEIVE_MESSAGE_FAILEDIncoming message webhook processing failed
RECEIVE_STATUS_FAILEDStatus callback webhook processing failed

Standard MessagingErrorCodes are also used — see the error codes reference.

Original provider codes

Twilio API errors (ApiException) are mapped to framework error codes in TwilioService.MapTwilioErrorCode():

Twilio codeMapped framework code
21211INVALID_RECIPIENT
21610INVALID_RECIPIENT
21614INVALID_SENDER
21408INVALID_SENDER
20001INVALID_MESSAGE
OtherSEND_MESSAGE_FAILED

Troubleshooting

SymptomLikely causeFix
INVALID_CREDENTIALSWrong AccountSid/AuthTokenCheck credentials in Twilio Console
INVALID_RECIPIENTPhone number not in E.164Use + prefix and country code
RATE_LIMITEDToo many requests per secondAdd delay between sends
MESSAGE_TOO_LARGESMS > 1600 charactersSplit into multiple messages
Delivery not receivedRecipient phone number issuesCheck Twilio Console logs
Status callback not receivedWebhook URL not reachableCheck callback URL and network

TwilioChannelSchemas

The connector ships with a predefined schema:

// Simple SMS schema (send only)
TwilioChannelSchemas.SimpleSms