SMS integration loop: send, deliver, reply, and recover
An SMS integration is more than a successfulPOST. Your application must retain the message id, consume delivery receipts, accept an inbound reply, and recover when the carrier rejects or never confirms delivery. This walkthrough puts those steps in one runnable loop.
Use a sandbox key first. The examples use the API base URL below and an SMS-capable number you own as from.
1. Map the endpoints
Keep these routes together in your integration:
All API calls use one base URL. The key selects sandbox or live mode; there is no separate sandbox host.
2. Start in the sandbox
Create adv_test_sk_... key and register your webhook with it. Sandbox traffic is simulated, free, and deterministic. Use the same request body and webhook code in production; when the loop passes, replace the key with a dv_live_sk_... key and use a live SMS-capable number.
A public HTTPS receiver is required. Subscribe to all four lifecycle names used by the message event family, plus inbound replies:
X-Orbit-Signature against the raw request body, deduplicate on the event id, and return 200 quickly before doing application work. Delivery is at-least-once, so a retry must not create a second reply or a second rollback.
Before switching to live, run the four sandbox cases in The test. A live key does not make the magic-number recipients safe: in live mode they are real destinations, not simulations.
3. Send the message
Send withPOST /messages/sms and keep the response’s data.id as your correlation key. The API returns 202 Accepted when Orbit has persisted and queued the message; it is not a delivery confirmation.
Body fields
tois the recipient in E.164 format, such as+14155552671. Normalize user-entered numbers with the E.164 formatter tool before sending.fromis your owned, SMS-capable number. It is optional when Orbit can choose an eligible sender, but pass it explicitly when you need stable two-way threading.bodyis the message text. It must be within the API payload-character limit. Its encoding determines how many carrier segments the message uses.Idempotency-Keyis a caller-generated key for safe retries. Reusing the key with the same body returns the original result; changing the body with the same key is rejected. Never use a new key to blindly retry a send after an uncertain timeout until you have reconciled the original request.
segments is the number of billable SMS segments calculated for this body. GSM-7 fits 160 characters in one segment and 153 characters per segment after concatenation. UCS-2 fits 70 characters in one segment and 67 per segment after concatenation. One emoji, smart quote, or other character outside GSM-7 can pivot the entire message to UCS-2. Preflight the rendered text with the SMS segment and cost calculator, including substituted names and footers.
For the complete error envelope, field-level fixes, and retry decisions, see API error handling by example. A 422 is a caller correction, not a delivery failure; an accepted send waits for its DLR.
4. Wire delivery and reply webhooks
Delivery receipts
Subscribe to the per-channel DLR events in Wire delivery-report webhooks per channel:message.sentmeans the send was accepted downstream. It is not delivery.message.deliveredmeans the carrier confirmed delivery to the handset.message.failedmeans a terminal failure such as a handset rejection, block, expiry, or no-receipt outcome. Readdata.status,error_code, anderror_messagewhen present.
data.message_id, not arrival order. SMS does not produce a read receipt, so do not wait for message.read to declare an SMS delivered. The DLR guide explains channel-specific windows and late correcting receipts.
A delivery event has this shape:
Inbound replies
The Send & Receive Messages guide is the canonical inbound route. A reply arrives asmessage.received on the same webhook; it is a new inbound message, not a response to the original HTTP request. Match the direction-aware from/to pair, normalize both numbers to E.164, and deduplicate on the event id or inbound message id.
A minimal handler should do this in order:
- Verify the signature over the raw body.
- Deduplicate the event id.
- Persist the inbound message and associate it with the conversation pair.
- Return
200. - Queue any business action or reply.
POST /messages/sms again with the endpoints swapped. Keep the same from number so the handset keeps one conversation thread. Never send outbound SMS through a different provider or bypass the Devotel softswitch.
5. The test
Run these four cases with a sandbox key before you flip to live. The trailing digit selects the simulation, as documented in the sandbox magic numbers playbook.
Use a separate test to exercise
message.received: have a sandbox handset or the sandbox inbound recipe send a reply to your number, then assert signature verification, deduplication, thread attribution, and your reply send. The first SMS, end to end guide is the longer setup path if you still need a number or API key.
Roll back a failed business action
SMS cannot be recalled after Orbit accepts it, and there is no API call that turns a delivered message back into an undelivered one. Roll back the business action attached to the message, not the carrier event:- Store your order or notification state as
pending_smswith themessage_id. - On
message.delivered, mark the notification complete. - On
message.failedor an expired no-receipt outcome, mark the action for retry or compensation according to your own tenant policy. - Retry only with a new idempotency key after correcting the cause or choosing a new recipient. Do not send a duplicate merely because a webhook was retried.
- If a late delivered receipt corrects a prior terminal event, accept the correction and reconcile your local state by
message_id.
Next steps
- Your first SMS, end to end — provision a number and build the longer first-send path.
- Send & Receive Messages — canonical inbound webhook and reply flow.
- Wire delivery-report webhooks per channel — event semantics, signatures, sandbox rehearsal, and debugging.
- API error handling by example — validation, rate limits, and retryable failures.
- SMS segment and cost calculator — preflight encoding, segments, and cost.
- E.164 formatter tool — normalize numbers before the send.