SMS
Sending SMS through Twilio, Telnyx, Bandwidth, Plivo, Sinch, Vonage, Bird, Termii, Infobip, Amazon SNS, or the managed sender, with regulatory and length pitfalls covered.
SMS is the most regulated channel. A wrong country code, missing opt-out phrase, or unregistered sender id can mean blocked messages, fines, or both. This page is the API-level checklist; the legal / regulatory work is on you.
Providers
MessagePipe ships several SMS adapters: Twilio, Telnyx, Bandwidth, Plivo, Sinch, Vonage, Bird SMS, Termii, Infobip, Amazon SNS, and MessagePipe (managed), which sends through our own account so you need no provider setup. See Providers for the credentials each one needs. Twilio, for example:
account_sid: ACxxxxxxxx
auth_token: ********
from_number: +18005551234 (or short-code / alphanumeric where supported)Sending an SMS
SMS sends go to POST /v1/sms/send. The body is flat: there is no content
wrapper, no channel field, and no recipient field. The phone number goes
in to.
curl https://api.dev.messagepipe.dev/v1/sms/send \
-H "Authorization: Bearer mp_live_..." \
-H "Content-Type: application/json" \
-d '{
"to": "+15551234567",
"body": "Your code is 123456. Reply STOP to opt out."
}'Or render a stored template. The variables field is data:
{
"to": "+15551234567",
"template": "otp-code",
"data": { "code": "123456" }
}to must be E.164 (+ + country code + number, no spaces).
MessagePipe rejects non-conforming numbers with validation_failed (HTTP
400) before hitting the provider so you don't burn carrier fees on typos.
A successful send returns 202 Accepted:
{
"id": "msg_01HZ...",
"status": "queued",
"channel": "sms",
"template_id": null,
"queued_at": "2026-06-23T12:00:00Z",
"_links": { "self": "/v1/sends/msg_01HZ..." }
}The identifier is id. Poll GET /v1/sends/{id} for status. Optional on any
send: scheduled_for (RFC3339) and idempotency_key (or the
Idempotency-Key header); idempotency is optional, not required.
Length and segmentation
A single SMS is 160 GSM-7 characters, or 70 UCS-2 characters if any character is non-GSM (emoji, curly quotes, accents). Messages over the limit are split into segments at the carrier: each segment counts as one credit.
| Encoding | Per segment | Trigger |
|---|---|---|
| GSM-7 | 160 chars | All chars in the GSM-7 set. |
| UCS-2 | 70 chars | Any character outside GSM-7 (one emoji is enough). |
Tip: curly quotes (’) silently switch you to UCS-2. Use ASCII ' if you
want to stay under one segment.
Compliance fields
US carriers require an opt-out instruction in the body of every commercial message:
Reply STOP to unsubscribe.Always include it on marketing traffic. Transactional (one-time codes, shipping updates) is generally exempt but check your carrier's terms.
Delivery events
A send moves through queued -> sent -> delivered | bounced | failed.
Twilio fires a callback for every status transition. MessagePipe maps:
| Twilio | Canonical |
|---|---|
queued | queued |
sent | sent |
delivered | delivered |
undelivered / failed | failed |
Read the current status with GET /v1/sends/{id}. There is no
/v1/sends/{id}/events endpoint, and no opened/clicked events.