SMS
Send SMS messages and track delivery status through the SMS channel.
The SMS endpoints let you send outbound text (SMS) and media (MMS) messages through a configured SMS use case and track their delivery lifecycle.
Send SMS
POST /v1/sms/
Sends a single SMS or MMS message through the messaging service associated with the specified SMS use case. Requires the sms:send scope on the target setup.
Before sending, the platform validates that:
The SMS use case exists and has not been deleted
At least one phone number is assigned to the use case's sender pool
The pool has an SMS-capable number (text-only sends) or an MMS-capable number (sends with media attachments)
For US long-code numbers, a verified A2P 10DLC campaign is associated with the use case
For US/CA toll-free or US long-code sender pools, the recipient has a recorded opt-in for the use case (sent via
POST /v1/sms/opt-in) and has not opted outFor US A2P and toll-free sends with a text body, the message content is consistent with the registered use case (A2P campaign and/or toll-free verification); content that does not match is rejected
The sender number is selected automatically from the use case's sender pool based on configured routing policies (sticky sender, area code geomatch). The chosen sender is not known at send time - it is resolved asynchronously and reported via the status callback.
Request Body (multipart form)
use_case_id
string (UUID)
Yes
ID of the SMS use case to send through
to_phone_number
string
Yes
Destination phone number in E.164 format
message
string
No
Message body, 1-1600 characters
media_attachments
file[]
No
Up to 10 media files; presence of any makes the message an MMS. Each file must be 1 byte to 600 KB with a unique, valid filename, and the total message size (body + attachments) must be under 5 MB.
At least one of message or media_attachments is required (422 otherwise).
Response (201)
id
string (UUID)
Unique identifier for the outbound SMS message
use_case_id
string (UUID)
SMS use case this message was sent through
message_sid
string
External message identifier used for delivery tracking
from_number
string or null
Sender phone number, null until resolved by the messaging service
to_number
string
Destination phone number
body
string or null
Message body that was sent, null for media-only messages
num_segments
integer or null
Number of message segments, null until carrier handoff
status
string
Current delivery status: pending, sent, delivered, failed, or undelivered
attachment_names
string[]
Filenames of any media attachments sent with the message
handed_off_at
string (datetime) or null
When the message was handed off to the carrier
delivered_at
string (datetime) or null
When the carrier confirmed delivery
errored_at
string (datetime) or null
When a delivery error occurred
error_code
integer or null
Error code on failed or undelivered messages
created_at
string (datetime)
When the message record was created
updated_at
string (datetime)
When the message record was last updated
Error Responses
401
Missing, expired, or invalid bearer token
403
Token lacks the required scope or access to this use case's setup
404
SMS use case not found or has been deleted
422
Neither message nor media_attachments provided
422
No phone number assigned to the use case
422
No SMS-capable number in the pool (text-only send) or no MMS-capable number (send with media)
422
No verified A2P campaign for a US long-code sender pool
422
No recorded opt-in for the recipient on a US/CA toll-free or US long-code sender pool
422
Message content does not match the registered use case
422
Invalid attachment (missing/duplicate/invalid filename, empty or over 600 KB, or total size 5 MB or more)
422
Invalid destination phone number (not a real number or is a landline)
422
Destination phone number has opted out of receiving messages
422
Destination region not permitted for the messaging service
422
The brand registration behind the use case is suspended
Delivery Status Lifecycle
After a message is sent, its status is updated automatically as delivery progresses:
The from_number field is populated once the messaging service selects a sender from the pool, which happens asynchronously after the send request returns.
On carriers without delivery receipt support (some international routes), the lifecycle stops at sent - delivered_at stays null, and handed_off_at is the only post-send signal.
Status Callback Handling
Delivery status updates flow back from the messaging provider through a status webhook that the platform configures automatically on each outbound message - no setup is required on your side. Webhook signatures are validated before processing, so forged status updates are rejected, and updates for unknown message identifiers are acknowledged and ignored.
Status updates are idempotent - duplicate callbacks for the same status transition are safely ignored. Late-arriving status updates that would regress a terminal state (for example, a sent callback arriving after delivered) are also dropped. The result is that the status, delivered_at, and error_code fields on a message record only ever move forward through the delivery lifecycle.
Last updated
Was this helpful?

