Track SMS
Every message, sent or received, has an id and comes back in the same shape wherever you see it: in API responses, in webhooks and in the events feed. To be told when a status changes instead of asking, use Events.
{ "id": "357913724415131648", "direction": "outbound", "kind": "transactional", "sender": "YourBrand", "recipient": "+447700900123", "country": "GB", "content": "Hi Sam, your order has shipped.", "channel": null, "status": "delivered", "reason": null, "hold": null, "parts": 1, "encoding": "gsm7", "cost": { "gbp": "0.0250", "eur": "0.0290" }, "clientReference": "order-991", "clientTag": null, "batchId": null, "validitySeconds": null, "expiresAt": null, "createdAt": "2026-10-10T09:30:00Z", "scheduledAt": null, "sentAt": "2026-10-10T09:30:01Z", "deliveredAt": "2026-10-10T09:30:04Z", "receivedAt": null, "updatedAt": "2026-10-10T09:30:04Z"}Fields that don’t apply are null. cost stays null until the delivery receipt tells us which network the number is on. See SmsMessageDto in the API reference for every field.
Status
Section titled “Status”| Status | Meaning |
|---|---|
queued | Accepted, scheduled, paced or held, and not yet sent |
sent | Handed to the network, with no delivery receipt yet |
delivered | The network confirmed delivery to the handset |
failed | Not delivered. reason says why |
cancelled | Cancelled before it was sent |
received | A reply or inbound message |
Failure reasons
Section titled “Failure reasons”reason is null unless the status is failed:
| Category | Meaning | Retryable |
|---|---|---|
invalid | The number, sender or message isn’t valid | No |
blocked | Blocked by a workspace or platform rule | No |
rejected | No route to the destination, or the country isn’t enabled for your workspace | No |
unreachable | The handset couldn’t be reached and the network stopped trying | Yes |
expired | The validity ran out before it could be sent | Yes |
undeliverable | The network reported a failure without a usable reason | No |
reason.code gives the exact cause, such as invalid_destination_address. retryable is true when the failure wasn’t caused by the message or the number, so sending it again later may work.
Looking up messages
Section titled “Looking up messages”GET /v2/sms/{id}gets one message, sent or received.GET /v2/smslists sent and received messages together, newest first. Filter bystatus,recipient,batchId,clientReferenceand more. Filtering bybatchId,clientReferenceorclientTagonly returns sent messages, as received messages don’t have them.GET /v2/sms/{id}/eventslists the events for one message, oldest first. Events are kept for 7 days. After that the timeline is empty, but the message still has its status and times.
Conversations
Section titled “Conversations”GET /v2/conversations lists your conversations, ordered by the latest message. Each one is the messages between one of your numbers (or a reply link) and one person.
To get the messages in a conversation, use GET /v2/sms with conversationWith set to the other person’s number.