Skip to main content

Worked request and response samples

Correlated message-ID lookup — GET /api/v1/messages accepts ?message_ids=<id1,id2,...> (up to 100) as a cross-channel delivery log search. Each id is OR-matched against the internal id OR the provider-assigned external_id (e.g. a Twilio MessageSid, a WABA message id, a Resend email id), so the provider id you already hold resolves the same row. Combine with channel / from_date / to_date to narrow.For POST /messages/batch, the full pipeline model — persist-then-attempt invariants, per-tenant caps and the safety ceiling, and per-recipient outcome rows — is on the Batch-send model concept page.
string
Search DSL — fielded field:value clauses AND-ed together. Supported fields include message_id, external_id, status, channel, direction, from, to, body, created, updated, conversation_id, contact_id. message_id and external_id both look up the provider-side identifier (Jasmin/SMPP receipt ref, Meta wamid, Resend email id, jambonz CallSid, Telnyx fax id) from the provider console. String fields support * wildcards. Invalid syntax or unknown fields return 400. See the Search message history guide.
Copy a request as written, substitute your own ids, and compare the response envelope. Errors follow Devotel Orbit’s { error, meta } envelope. The chain a sender runs: send → poll → receive the delivery webhook.

1. Send an SMS

POST /api/v1/messages/sms
Request
The returned id is the handle you poll and that webhook deliveries reference. Sandbox sends terminate at test_sent instead of queued/provider states; when you authenticate with a sandbox key the meta block carries test_mode: true and the message row settles at test_sent:
string
queued on live sends; test_sent on sandbox/test-mode sends. Poll GET /api/v1/messages/{id} (below) for transitions.

2. Poll the message status

GET /api/v1/messages/{id}
Request
Typical transition order: pending → queued → sent → delivered. Terminal failures land on failed / rejected / undelivered / expired. The full lifecycle, including every status the filter accepts, is on the status lifecycle page.

3. Delivery receipts via webhook

Terminal transitions also send a message.delivered / message.failed event to your webhook_url or subscribed endpoint. The delivery-receipt wire shape (envelope, signature headers, retry behaviour) is documented in Webhook event payloads — subscribe to message.delivered and message.failed rather than polling.

4. Send errors to handle

Invalid recipient → 422 INVALID_PHONE_NUMBER. The pre-send numbering-plan check rejects unrouteable destinations before a provider call:
422
Empty wallet → 402 INSUFFICIENT_BALANCE. Top up your balance and resend:
402

5. Create a message template

POST /api/v1/messages/templates
The same request shape returns a created-record envelope on 201. Approval-required channels (WhatsApp, RCS, Kakao, Zalo) come back draft and move to pending on carrier submission; platform-only channels (SMS, email, Viber) land active and are immediately sendable. Full lifecycle on Outbound templates.
For the cross-channel author layer (Twilio Content API parity), group per-channel variants with a fallback order under one logical id:
POST /api/v1/messages/content-templates