Skip to main content

Twilio Send ExecModule

Overview

TwilioSendModule creates one outbound Twilio Message resource for SMS, MMS, or WhatsApp. Version 2.0 replaces the former catalog-empty and mockable implementation with strict request validation, bounded transport, IntegrationAccount-only credentials, verified provider results, and secret-safe failures.

The module reports success only after Twilio returns a valid SM or MM Message SID and an initial status. Message creation is an external, non-idempotent action. The module never fabricates a SID and never retries automatically after rate limits, provider failures, timeouts, or ambiguous network outcomes.

Usage

  1. Create or select a Twilio account authorized for Programmable Messaging.
  2. Store the Account SID and Auth Token in a ValkyrAI IntegrationAccount and set its status to READY.
  3. Bind that account through ExecModuleConfig.authConfig.integrationAccount.
  4. Select SMS or WHATSAPP, configure an E.164 recipient, and provide an explicit sender or Messaging Service SID.
  5. Supply a body, HTTPS media URLs, or a Content Template SID. Do not combine a body with a Content Template.
  6. Apply outbound approval where workflow policy requires it, then reconcile the Twilio Message SID before manually retrying an ambiguous failure.

Inputs

NameTypeRequiredDescriptionConstraints
channelstringYesSMS or WHATSAPP.Case-insensitive; normalized to uppercase.
tostringYesRecipient phone number.E.164 format. The module adds whatsapp: for WhatsApp.
fromstringConditionalTwilio sender phone number.E.164 format; required when messaging_service_sid is absent.
messaging_service_sidstringConditionalTwilio Messaging Service.MG followed by 32 hexadecimal characters.
bodystringConditionalSMS, MMS, or free-form WhatsApp content.1–1,600 Unicode code points; cannot be combined with content_sid.
media_urlsarray of stringsNoMedia Twilio retrieves for the message.At most ten HTTPS URLs; embedded credentials and fragments are rejected.
content_sidstringConditionalApproved Twilio Content Template.HX followed by 32 hexadecimal characters; cannot be combined with body or media.
content_variablesobjectNoValues for a Content Template.Requires content_sid; serialized once as the ContentVariables JSON object.

At least one of body, media_urls, or content_sid is required. Legacy whatsapp_template and template_vars names are accepted as aliases for migration, but new workflows should use the canonical names above. A legacy mock value is rejected.

Outputs

NameTypeWhen presentDescription
twilio.message.sidstringVerified successTwilio SM or MM Message SID.
twilio.message.statusstringAlwaysInitial Twilio status such as queued, or ERROR on failure.
twilio.message.channelstringVerified successNormalized SMS or WHATSAPP.

The initial status confirms that Twilio accepted or created the Message resource; it is not proof of delivery. Delivery tracking belongs in a status-callback workflow or an explicit message-read operation.

IntegrationAccount Requirements

SettingRequirement
ProviderTwilio Programmable Messaging
StatusREADY
apiKeyEncrypted Twilio Account SID beginning with AC
passwordEncrypted Twilio Auth Token
RelationshipBind through ExecModuleConfig.authConfig.integrationAccount

Do not place the Auth Token, Account SID, or generated Basic authorization value in payload parameters, workflow content, logs, errors, or documentation examples. Restricted Twilio API keys and OAuth credentials are not mapped by this module's v2 credential contract.

Configuration

Illustrative normalized configuration:

{
"version": "2.0.0",
"authConfig": {
"authStrategy": 1,
"integrationAccount": "integration-account:twilio-production"
},
"payloadConfig": {
"parameters": "{\"channel\":\"SMS\",\"to\":\"+14155550123\",\"from\":\"+14155550999\",\"body\":\"Your order is ready.\"}"
}
}

The account value is a symbolic secure relationship, not a credential. The default transport uses a 10-second connection timeout and a 30-second read timeout. Redirects and retries are not part of the module-level send contract.

Operations

TwilioSendModule performs one provider operation: POST /2010-04-01/Accounts/{AccountSid}/Messages.json.

ShapeProvider fieldsSide effect
SMSTo, From or MessagingServiceSid, BodyCreates one text Message resource.
MMSSMS fields plus one or more MediaUrl fieldsCreates one media-bearing Message resource.
WhatsApp free-formWhatsApp-prefixed To/From plus BodyCreates one WhatsApp message subject to the conversation window and account policy.
Content TemplateAddresses plus ContentSid and optional ContentVariablesCreates one templated Message resource.

Bulk send, scheduling, message lookup, delivery callbacks, redaction, deletion, and Messaging Service management are not implemented by this module.

Errors and Failure Modes

FailureCauseRetry guidance
Validation failureMissing content, invalid E.164 number or SID, insecure media URL, conflicting body/template inputs, or a legacy mock request.Correct configuration; no Twilio request was sent.
IntegrationAccount failureNo bound account, non-READY status, malformed Account SID, or missing Auth Token.Repair the secure account binding; no Twilio request was sent.
HTTP 400/403/404Invalid payload, account policy, sender, recipient, template, media, or resource state.Correct the request or account before a deliberate new attempt.
HTTP 401Invalid, expired, or rotated Account SID/Auth Token pair.Rotate the IntegrationAccount credentials before retrying.
HTTP 429Provider rate limit.Reconcile provider state and retry later; the module does not retry automatically.
HTTP 5xx or network failureProvider or transport failure with an ambiguous create boundary.Search Twilio message records before a deliberate retry to avoid duplicates.
Invalid 2xx responseMissing or malformed Message SID or status.Treat as failure and inspect provider compatibility; success is not recorded.

Provider response bodies may contain message content, phone numbers, or credential-like values. Failures therefore expose only a sanitized HTTP status or bounded local validation message.

Example

Send one WhatsApp Content Template through a Messaging Service:

{
"channel": "WHATSAPP",
"to": "+14155550123",
"messaging_service_sid": "MGabcdef0123456789abcdef0123456789",
"content_sid": "HX0123456789abcdef0123456789abcdef",
"content_variables": {
"1": "22 July 2026",
"2": "3:15pm"
}
}

Expected result shape after Twilio returns a valid Message resource:

{
"twilio.message.sid": "SMabcdef0123456789abcdef0123456789",
"twilio.message.status": "queued",
"twilio.message.channel": "WHATSAPP"
}

Notes

  • Pagination: not applicable; one execution attempts one Message creation.
  • Limits: the module caps content at 1,600 Unicode code points and media at ten HTTPS URLs. Twilio and carrier/channel rules may impose stricter limits, segmentation, type, size, or template requirements.
  • Rate limits: HTTP 429 is surfaced without retrying. Reconcile whether Twilio created a Message before any new attempt.
  • Idempotency: Twilio Message creation has no module-level idempotency key. A workflow retry can create a duplicate message.
  • API constraints: sender registration, WhatsApp session windows, template approval, regional policy, carrier filtering, and media retrieval remain provider-controlled.
  • Destructive behavior: the operation sends customer-facing content and may incur provider charges. The module cannot recall or compensate a delivered message.
  • Observability: EventLogs record validation, submission, verified Message SID, or a sanitized failure. Phone numbers, content, credentials, and provider bodies are excluded.
  • Unverified boundary: deterministic tests cover account binding, exact form construction, validation, template-variable serialization, response mapping, non-retry behavior, metadata serialization, and redaction. Live Twilio execution requires separately authorized service credentials and is not exercised in repository tests.

See Twilio's official Messages resource and WhatsApp quickstart for provider-side requirements.