Skip to main content
Version: v1.1.2

Twilio WhatsApp Connector

WhatsApp Business messaging through Twilio's API for WhatsApp.

Package​

dotnet add package Ratatosk.Twilio

Required settings​

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

Optional settings​

ParameterTypeDescription
WebhookUrlstringURL for inbound WhatsApp messages
StatusCallbackstringURL for delivery status callbacks

Number format​

Phone numbers must use the whatsapp: prefix with E.164 format:

new MessageBuilder()
// Sender — must be a Twilio WhatsApp-enabled number
.FromPhone("whatsapp:+14155238886") // Twilio's default WhatsApp number
// Recipient — must have opted in to receive messages from your business
.ToPhone("whatsapp:+15550002222")
.WithText("Hello")
.Build();

Schema​

PropertyValue
ProviderTwilio
TypeWhatsApp
Version1.0.0
CapabilitiesSendMessages, MessageStatusQuery, Templates
Content typesPlainText, Media, Template
EndpointsPhoneNumber (send + receive)
AuthenticationBasic (AccountSid + AuthToken)

Send examples​

Text message​

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

var connector = new TwilioWhatsAppConnector(TwilioChannelSchemas.TwilioWhatsApp, settings);
await connector.InitializeAsync(ct);

var message = new MessageBuilder()
.WithId("wa-1")
.FromPhone("whatsapp:+14155238886")
.ToPhone("whatsapp:+15550002222")
.WithText("Hello from WhatsApp!")
.Build();

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

Template message (for business-initiated conversations)​

WhatsApp requires approved templates for the first message to a user:

var message = new MessageBuilder()
.WithId("wa-template-1")
.ToPhone("whatsapp:+15550002222")
.WithContent(new TemplateContent("order_confirmed", new Dictionary<string, object?>
{
["order_id"] = "ORD-123",
["delivery_date"] = "2026-05-15"
}))
.Build();

Media message with caption​

new MessageBuilder()
.FromPhone("whatsapp:+14155238886")
.ToPhone("whatsapp:+15550002222")
.WithContent(new MediaContent(MediaType.Image, "product.jpg",
"https://example.com/product.jpg"))
.WithProperty("caption", "Check out our new product!")
.Build();

Message properties​

PropertyTypeDescription
captionstringCaption for media messages
ValidityPeriodintMessage validity in seconds

Webhook handling​

Similar to Twilio SMS — inbound messages arrive as form POST with MessageSource.UrlPost():

[HttpPost("/webhooks/twilio/whatsapp")]
public async Task<IActionResult> WhatsAppWebhook(CancellationToken ct)
{
using var reader = new StreamReader(Request.Body);
var body = await reader.ReadAsStringAsync(ct);
var source = MessageSource.UrlPost(body);

var result = await _connector.ReceiveMessagesAsync(source, ct);
return TwiML.Empty;
}

Validate X-Twilio-Signature header before processing.

Error codes​

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

CodeDescription
INVALID_CONNECTION_SETTINGSConnection settings validation failed
MISSING_FROM_NUMBERSender WhatsApp number is required
INVALID_SENDERSender number is not in valid whatsapp:+E164 format
INVALID_MESSAGEMessage properties failed schema validation
MISSING_CONTENT_SIDWhatsApp template Content SID is missing
INVALID_WHATSAPP_NUMBERWhatsApp number does not follow required 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_RECIPIENTNumber without whatsapp: prefixUse whatsapp:+E164 format
Template rejectedTemplate not approvedVerify template status in Twilio Console
RATE_LIMITEDToo many messagesWhatsApp has per-conversation limits
No deliveryUser hasn't opted inUser must send first message or accept invite
Media not sentUnsupported formatCheck WhatsApp media requirements (max 64MB, specific formats)

TwilioChannelSchemas​

// WhatsApp messaging schema
TwilioChannelSchemas.TwilioWhatsApp