Twilio
Send SMS, MMS, and WhatsApp messages to your customers via the Twilio Programmable Messaging API. Zeotap sends one message per row in your sync, with deep support for Twilio Content templates (pick a template, map columns to its variables) and Messaging Services (sender pools), plus a freeform message template powered by your warehouse data.
Prerequisites
- A Twilio account with Programmable Messaging enabled
- Your Twilio Account SID (found in the Twilio Console )
- Either your Auth Token or an API Key SID + Secret (recommended for production)
- A Twilio phone number or a Messaging Service capable of sending on your chosen channel
- For WhatsApp: an approved WhatsApp sender and an approved Content template
Permissions
Your Twilio account must have:
- An active, non-suspended status
- At least one phone number or Messaging Service provisioned for the channel you send on
- Sufficient account balance or auto-recharge enabled for message delivery
Authentication
Twilio uses HTTP Basic Auth. Zeotap supports two credential methods. The Account SID is always required — it forms the API URL path.
Account SID + Auth Token
- Log in to the Twilio Console
- On the dashboard, copy your Account SID (starts with
AC) - Click the eye icon next to Auth Token to reveal and copy it
- In Zeotap, choose Account SID + Auth Token and paste both values
API Key SID + Secret (recommended)
API Keys can be revoked individually without rotating your master Auth Token, so they are preferred for production.
- In the Twilio Console, go to Account → API keys & tokens → Create API key
- Copy the API Key SID (starts with
SK) and the Secret (shown only once) - In Zeotap, choose API Key SID + Secret, paste your Account SID, the API Key SID, and the Secret
Configuration
Twilio does not require account-level configuration fields beyond authentication. All send settings are per-sync Target Settings (below).
Target Settings
These settings apply to the destination and can be overridden per sync.
| Field | Type | Required | Description |
|---|---|---|---|
| Channel | Select | No | SMS / MMS (default) or WhatsApp. WhatsApp requires a Content template and the whatsapp: prefix is added automatically. |
| Messaging Service | Select | No* | A Twilio Messaging Service (MG…) sender pool. Recommended. Takes precedence over From Phone Number and is required for scheduled sends. Choose from a live dropdown of your account’s services. |
| From Phone Number | Select | No* | A Twilio phone number (E.164, e.g. +15551234567) to send from. Used when no Messaging Service is set. Choose from your account’s numbers or type one. |
| Content Template | Select | No** | A Twilio Content template (HX…). When set, the message body comes from the template and its variables are filled from your mapped fields. Choose from a live dropdown of your account’s templates. |
| Message Template | Textarea | No** | Freeform message body with {{field_name}} placeholders replaced by row values. Used only when no Content Template is selected. Maximum 1,600 characters after substitution. |
| Status Callback URL | Text | No | Webhook URL Twilio POSTs delivery status updates to. A per-row status_callback field overrides this. |
* Provide one of Messaging Service or From Phone Number. ** Provide one of Content Template or Message Template. WhatsApp requires a Content Template.
Content Templates & Variables
Twilio Content templates are the recommended way to author messages — they are the equivalent of SendGrid dynamic templates. A template defines placeholder variables (written {{1}}, {{2}}, or named) that you fill in at send time.
When you select a Content Template in Zeotap:
- Zeotap reads the template’s variables from Twilio and shows them as destination fields in the mapping editor (schema introspection).
- Map a warehouse column to each template variable.
- At send time, Zeotap builds Twilio’s
ContentVariablesobject from your mapped fields and sends it with the template’sContentSid.
Any mapped field that is not a reserved routing field (to, from, body, media_url, status_callback) becomes a Content Variable. For example, a template body of Hi {{1}}, your code is {{2}} is filled by mapping columns to the 1 and 2 destination fields.
If you do not select a Content Template, Zeotap uses the freeform Message Template instead, replacing {{column_name}} placeholders directly with row values.
To send on WhatsApp:
- Set Channel to
WhatsApp. - Configure a Messaging Service (or a WhatsApp-enabled From number) and an approved Content Template.
- Map the
tofield to recipient phone numbers in E.164 format — Zeotap adds thewhatsapp:prefix automatically.
WhatsApp messages must use a template that has been approved by WhatsApp (submitted via the Twilio Console; approval typically takes up to one business day). Plain SMS does not require template approval.
Supported Operations
Sync Modes
| Mode | Supported |
|---|---|
| Insert | Yes |
| Upsert | — |
| Update | — |
| Mirror | — |
Twilio is an append-only messaging API. Each sync run sends a new message for every row. There is no concept of updating or deleting a previously sent message.
Audience Sync Modes
| Mode | Supported |
|---|---|
| Add | Yes |
| Remove | — |
| Mirror | — |
When syncing an audience, Zeotap sends one message to each member as they enter the audience (Add). Twilio has no list- or segment-membership API, so members cannot be programmatically removed or unsubscribed — recipients opt out using carrier keywords (STOP), which Twilio enforces and reports as error 21610 on subsequent sends.
Features
- Field Mapping: Yes
- Schema Introspection: Yes (Content template variables)
Required Mapping Fields
| Field | Description |
|---|---|
| to | Recipient phone number in E.164 format (e.g. +15551234567). For WhatsApp the whatsapp: prefix is added automatically. |
Default Destination Fields
to, from, body, media_url, status_callback
from— optional per-row sender override (E.164). Ignored when a Messaging Service is configured.body— optional explicit body, used in freeform mode when the Message Template has no placeholders.media_url— a publicly reachable media URL to send as MMS.status_callback— optional per-row delivery-status webhook, overrides the destination-level Status Callback URL.
When a Content Template is selected, its variables also appear as mappable fields.
How It Works
- Zeotap reads rows from your configured model or audience
- For each row, it builds a message:
- With a Content Template:
ContentSidplus aContentVariablesobject built from your mapped fields - Otherwise: the Message Template is rendered by replacing
{{field_name}}placeholders with row values
- With a Content Template:
- The sender is set from your Messaging Service (
MessagingServiceSid) or From Phone Number (From) - A
POSTrequest is sent tohttps://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages.jsonwith form-encoded parameters - If a
media_urlfield is mapped, it is included asMediaUrlto send an MMS - If a Status Callback URL (or per-row
status_callback) is set, it is included for delivery-status webhooks - Messages are sent one at a time per row (Twilio does not offer a batch send endpoint)
- Failed messages are retried up to 3 times with exponential backoff;
429 Too Many Requestsand5xxerrors trigger automatic retries
Batch Size
Messages are sent individually (1 per API call). Zeotap processes rows sequentially within each batch to respect Twilio account-level rate limits.
Error Handling
- Invalid phone number: Twilio returns a descriptive error; the row is marked as failed
- Rate limiting (429): Zeotap automatically retries with exponential backoff
- Server errors (5xx): Retried up to 3 times before marking the row as failed
- Authentication failure (401): The send fails with an authentication error
- Per-row delivery failures: Twilio reports invalid/opted-out/unreachable recipients with an
error_codeanderror_message, surfaced on the failed row
Rate Limits
Twilio enforces per-sender throughput limits and account-level concurrency on API requests. During high-volume sends:
- You may receive
429 Too Many Requestsresponses, which Zeotap handles automatically with retries - Monitor your Twilio Console for the Twilio-Concurrent-Requests header to understand current utilization
- For high-throughput use cases, use a Messaging Service with a pool of numbers, which queues and drains messages at your account throughput
Default SMS throughput varies by sender type: US long codes (A2P 10DLC) depend on your registered campaign and Trust Score; toll-free numbers support up to 3 messages per second; short codes support 100+ messages per second. Messages that exceed your throughput are queued at the account level and drain at your sending rate.
Best Practices
- Use E.164 format for all phone numbers (e.g.
+15551234567) to ensure reliable delivery - Prefer Content Templates over freeform bodies — they support variable validation, are required for WhatsApp, and let you map columns directly onto template variables
- Use a Messaging Service for the sender to benefit from automatic sender selection, sticky sender, opt-out handling, and higher pooled throughput
- Keep SMS messages concise — messages over 160 GSM-7 characters (or 70 UCS-2 characters) are split into multiple segments, each billed separately
- Test with a small audience first before sending to large segments to validate your template and variables
- Map a Status Callback URL if you need delivery receipts for tracking message status
- Monitor your Twilio balance — messages fail if your account runs out of funds
Troubleshooting
Authentication failed: invalid Account SID, Auth Token, or API Key
Verify your credentials in the Twilio Console . The Account SID starts with AC. If using an API Key, the SID starts with SK and the Secret is shown only once at creation — recreate the key if you lost it. If you recently rotated your Auth Token, update it in Zeotap.
Error 21211: Invalid ‘To’ Phone Number
The destination number is not a valid phone number. Check that your source column contains properly formatted E.164 numbers (e.g. +15551234567), not names or email addresses.
Error 21610: Message cannot be sent to an unsubscribed recipient
The recipient previously sent STOP and is opted out of this sender or Messaging Service. Twilio blocks the send. The recipient must text START/UNSTOP to opt back in — this cannot be done via the API.
Error 21654 / 92005: ContentSid is required or invalid
The selected Content Template ID is missing or malformed. Re-select the template from the Content Template dropdown, and confirm it exists in your Twilio account under Messaging → Content Template Builder.
Error 21656: ContentVariables is invalid
The variables sent for the Content Template could not be parsed. Confirm your mapped fields correspond to the template’s variables and that values are simple strings.
Error 63016 / WhatsApp template not approved
A WhatsApp message was sent with a template that is not approved, or freeform content was sent outside the 24-hour customer service window. Submit the template for approval in the Twilio Console and wait for approval before sending.
Error 35118: A Messaging Service is required to schedule messages
Scheduled sends require a Messaging Service. Configure a Messaging Service instead of a raw From Phone Number.
Error 21608: The number is unverified
In Twilio trial accounts, you can only send messages to verified phone numbers. Upgrade to a paid account or verify the recipient number in the Twilio Console under Verified Caller IDs.
Error 30003: Unreachable destination handset
The recipient’s phone is turned off, out of coverage, or has blocked SMS. This is a carrier-level issue reported asynchronously via the Status Callback. Consider retrying transient delivery failures on your sync schedule.
MMS not sending: missing MediaUrl
To send MMS, map a media_url field containing a publicly accessible URL to the media file. The URL must be reachable by Twilio’s servers. Supported formats include JPEG, PNG, and GIF (up to 5 MB).
Messages are being sent slowly
Zeotap sends messages sequentially to respect Twilio rate limits. For higher throughput, use a Twilio Messaging Service with a pool of numbers, or short codes / toll-free numbers which support higher send rates.