CPaaS / SMS API
How to switch from Twilio
A code swap, not a data migration: the send-call diff, sender IDs re-registered, opt-outs carried over, and status callbacks remapped — with a phased rollout so nothing critical breaks.
Half a day of code changes; sender-ID registration sets the calendar (days to weeks per country)
| Twilio | WeZend |
|---|---|
| Messages API (POST /Messages) | POST /v1/messages/send |
| Account SID + Auth Token | X-API-Key header |
| Messaging Services / sender pool | Automatic routing + registered senders |
| Status callbacks | Delivery webhooks (signed) |
| Advanced Opt-Out lists | Suppression list + STOP handling |
| Inbound webhooks (MO) | Inbound webhook + Inbox |
| Twilio Verify (OTP) | Transactional sends + voice fallback journey |
| Programmable Voice (TTS) | Voice channel |
What kind of migration this is
Twilio holds very little of your data — it's infrastructure your code calls. So this migration is 90% a controlled code swap and 10% regulatory logistics (sender registration). The golden rule: route by feature flag, not by big bang, so you can shift traffic gradually and roll back instantly.
Step 1 — Start the slow clock: sender IDs
Registration lead time is the only thing you can't compress, so do it first. List every sender you use (alphanumeric names, numeric senders) and every destination country, then register them under Settings → Senders (POST /v1/senders). Check per-country requirements programmatically:
curl "https://api.wezend.com/v1/sender/rules?country=DK" -H "X-API-Key: $WEZEND_API_KEY"
Countries with operator registration take days to weeks — start now, code later.
Step 2 — Carry the opt-outs over
If you use Twilio's Advanced Opt-Out (or track STOPs yourself), export those numbers and import them as suppressions. WeZend intercepts STOP/START keywords automatically going forward, but history must come with you — a recipient who said STOP on Twilio must stay stopped on WeZend.
Step 3 — The code diff
Twilio (Node):
const twilio = require("twilio")(ACCOUNT_SID, AUTH_TOKEN);
await twilio.messages.create({
to: "+4512345678",
messagingServiceSid: "MG…",
body: "Your code is 493202",
statusCallback: "https://api.yourapp.com/sms-status",
});
WeZend — plain HTTP, no SDK required:
await fetch("https://api.wezend.com/v1/messages/send", {
method: "POST",
headers: { "X-API-Key": process.env.WEZEND_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
to: "+4512345678",
channel: "sms",
sender: "Acme",
message: "Your code is 493202",
category: "transactional",
webhook_url: "https://api.yourapp.com/sms-status",
}),
});
Differences that matter:
- Auth is one header (
X-API-Key), no SID/token pair. Keys rotate with a 24-hour grace window. messagingServiceSiddisappears — routing to the best vendor per destination is the platform's job, with automatic failover when a route degrades.category: "transactional"marks OTPs and receipts so they bypass marketing caps and quiet hours.- Status callbacks arrive on your
webhook_urlwith anX-WeZend-SignatureHMAC — verify it. Map statuses: Twilio'squeued/sent/delivered/undelivered/failedcorrespond toqueued/sent/delivered/failed(undelivered and failed both arrive asfailed, with the reason attached).
Step 4 — Inbound and two-way
Point your reply handling at WeZend: set the inbound webhook URL and inbound messages POST to your endpoint just like Twilio's MO webhooks did — plus they land threaded in the Inbox, which your support team gets for free.
Step 5 — Phased rollout
Put the provider choice behind a flag and shift traffic in stages: 5% → verify delivery rates against Twilio's baseline → 50% → 100%. Keep the Twilio account alive (it costs nearly nothing idle) until every webhook consumer is migrated and a full billing cycle has passed. When something fails during the transition, the Delivery Inspector shows the carrier-level reason in plain language — no more decoding error 30008.
What about Verify, Voice and numbers?
- OTP flows: send with
category: "transactional"; add the "no delivery in N seconds → voice call" fallback as a two-step journey. - Voice/TTS: the voice channel covers automated TTS calls and alerts.
- Dedicated long codes/short codes: number porting is handled case by case — contact us with your numbers and destinations before you schedule the cutover.
Go-live checklist
- All sender IDs registered per destination country (start immediately — longest lead time)
- Twilio opt-out lists exported and imported as suppressions
- Send calls swapped behind a feature flag; category set on transactional traffic
- Webhook consumer verifies X-WeZend-Signature and maps statuses
- Inbound webhook URL set; replies verified end-to-end
- Traffic shifted 5% → 50% → 100% with delivery rates compared at each step
- Twilio account kept alive until a full billing cycle passes cleanly
Frequently asked about switching from Twilio
Is there an SDK, or do we call the REST API directly?
The API is plain JSON-over-HTTPS designed to be called directly — the examples above are complete. That also means an AI assistant can write the integration for you: our whole API is machine-readable at /llms-full.txt, and the Build-with-AI guide shows the workflow.
Twilio charges per segment — how does WeZend price SMS?
Also per segment, per destination — that's how carriers bill, and pretending otherwise hides costs. The difference is transparency: GET /v1/account/pricing returns your exact rates, the dashboard shows segment count and price before you send, and the same prepaid balance covers every channel.
What do we gain beyond a like-for-like API swap?
Everything around the send: automatic vendor failover, the Delivery Inspector for plain-language failure reasons, a shared Inbox for replies, and — when you're ready — the CDP, journeys and email/WhatsApp/push on the same API and balance. You migrate an SMS provider; you arrive at a platform.
Start free in minutes
- No credit card
- EU data residency
- 6 channels, one API
- GDPR built in
One platform. Every customer interaction.
Replace your patchwork of messaging APIs, CDP and automation tools with a single engagement platform built for scale.
No credit card required · EU data residency · 99.99% uptime SLA