SMS sending services
A messaging service is a reusable sender profile: one container that bundles the sender pool (which of your numbers send), the opt-out list (which STOP/HELP keywords and auto-replies apply), and the inbound-reply webhook (where incoming messages land). Once a service exists, you point sends at its id and get the same configuration on every message instead of repeatingfrom numbers and webhook URLs per send.
This guide covers the full lifecycle: create a service in the console or with POST /api/v1/messaging/services, attach numbers, wire the opt-out list and inbound webhook, and send through it. For the endpoint shapes, see the Messaging Services API reference; for the sender-pool rotation strategies a service’s pool can use, see Sender pools.
1. When to create a service vs an ad-hoc sender
Create a service when any of these hold:- More than one sender per channel — a single hardcoded
fromnumber throttles and burns carrier reputation; a service with a pool rotates senders per recipient. - Branded compliance — if you send under more than one brand, you want that brand’s STOP/HELP copy on every message, not the platform defaults.
- Two-way SMS — inbound replies need one webhook URL that every sender number in the service points at.
- Migration from Twilio — if you’re mapping a
MessagingServiceSid(MGxxx) over, the Orbit service is the equivalent container.
from is fine. The service exists to stop the “same four fields on every send” repetition once you’re past that.
2. Create a service
In the console
Open Messages → SMS → Services (/messages/sms/services) and click New service. The list page creates, edits, and deletes services; drilling into a service opens its Config, Phone Numbers, and Inbound Webhook tabs. Anything you can do in those tabs is available through the API below on the same service id.
Via the API
Onlylabel is required — the rest of the config attaches later:
msvc_xxx), which is what sends reference. Owner or admin scope is required; a duplicate external_id (used for Twilio MGxxx migration) returns 409.
3. Attach numbers, opt-out list, and inbound webhook
Sender numbers
You have two ways to give a service senders, and most services want the pool:- Sender pool (recommended) — set
sender_pool_id(or per-countrycountry_sender_pools) so the service resolvesfromthrough a named pool’s strategy. See Sender pools forsticky/round_robin/random/geomatchbehavior. - Direct phone-number attachment — for a fixed DID rather than a pool, attach specific tenant-owned numbers. SMS-capable DIDs only; voice/MMS-only DIDs are rejected with 422, and re-attaching the same number is idempotent:
Opt-out (STOP/HELP) list
Setopt_out_list_id on the service to point at a custom list — extra keyword aliases plus branded STOP/HELP/START auto-reply text. The platform’s carrier-mandated defaults always merge in; your list can add to but never remove STOP itself. For list creation and field details, see Custom Opt-Out Keyword Lists. Set opt_out_list_id back to null to fall back to the platform defaults.
Inbound-reply webhook
Setinbound_webhook_url (and optional inbound_method, default POST) so every inbound reply to any sender in the service POSTs to your endpoint. Optional fallback_url and status_callback fields further direct delivery-status events. Webhook URLs are validated server-side to block internal/private addresses — use a public HTTPS URL.
4. Send through the service
Passmessaging_service_id on the message instead of per-field from/webhook values. Any field you set explicitly on the message still wins; the service supplies the rest, matching Twilio’s MessagingServiceSid contract:
mps_cap, quiet hours, send gates) apply the same way as any other send; per-service mps_cap lets you throttle one profile below the tenant limit.
5. Multi-sender rotation and fallback
Rotation behavior is the sender pool’s strategy, not the service’s — the service just resolves through the pool each send:stickykeeps a recipient on the same sender so two-way threads stay on one number.round_robinspreads volume evenly across pool members.geomatchpicks a sender from the recipient’s country when one exists in the pool, falling back to the pool’s remaining senders rather than failing the send.randomrotates statelessly per send.
GET /messaging/sender-pools/{id}/preview) before routing traffic.
6. Troubleshooting
See also
- Messaging Services API reference — endpoint contract for every operation above
- Sender pools — rotation strategies a service’s pool can use
- Custom Opt-Out Keyword Lists — branded STOP/HELP copy and keyword aliases
- Batch SMS — the one-off multi-recipient send surface that can reference a service
- Sending and receiving messages — the
POST /messagesflow that carriesmessaging_service_id