Skip to main content
Version: v1.1.1

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
MessagingServiceSidstring—Twilio Messaging Service SID for advanced routing
WebhookUrlstring—URL for inbound SMS and status callbacks
StatusCallbackstring—URL for delivery status callbacks
ValidityPeriodint—Message validity in seconds (14400 = 4 hours default)
MaxPricedecimal—Maximum price per message
SmartEncodedbool—Optimize 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