Channel Routing and Fallback Behavior in the Sent API

Channel routing selects the channel (sms, whatsapp, rcs, or mms) and the underlying provider for every message accepted by POST /v3/messages. This page defines the accepted channel values, the resolution rules behind the default sent auto-detect channel, fallback behavior, and where the resolved channel appears in API responses, message records, and webhooks.

For the design rationale behind auto-detection, see Unified Messaging Intelligence. For what each channel supports, see Channels.


Channel Values

POST /v3/messages accepts channel as an array of strings. Allowed values:

ValueBehavior
sentAuto-detect: routing selects the channel per recipient at send time. Default when channel is omitted.
smsPins the message to SMS.
whatsappPins the message to WhatsApp.
rcsPins the message to RCS.
mmsPins the message to MMS. Requires allowMms on the account; see MMS.
  • Omitting channel or sending an empty array is equivalent to ["sent"].
  • Any other value fails request validation and the request is rejected with a 400 error.
  • The array is a broadcast list, not a fallback priority list. Each entry creates a separate message per recipient: "channel": ["whatsapp", "sms"] with two recipients creates four messages. There is no fallback field; fallback is a property of routing, described below.
  • The 202 response echoes the request per message in recipients[].channel. Auto-detect entries appear as "sent".
curl -X POST https://api.sent.dm/v3/messages \
  -H "x-api-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["+14155551234"],
    "template": { "name": "order_confirmation", "parameters": { "name": "John" } }
  }'
{
  "success": true,
  "data": {
    "status": "QUEUED",
    "template_id": "7ba7b820-9dad-11d1-80b4-00c04fd430c8",
    "template_name": "order_confirmation",
    "recipients": [
      {
        "message_id": "8ba7b830-9dad-11d1-80b4-00c04fd430c8",
        "to": "+14155551234",
        "channel": "sent",
        "body": "Hi John, your order has been confirmed."
      }
    ]
  },
  "error": null,
  "meta": {
    "request_id": "req_7X9zKp2jDw",
    "timestamp": "2026-07-25T10:30:00Z",
    "version": "v3"
  }
}

How Auto-Detect Resolves a Channel

A message on the sent channel is matched against routing rules at send time, after the request has already been accepted with 202. Routing rules are created and maintained by the platform from your channel setup:

  • Connecting a WhatsApp Business account creates an account-scoped WhatsApp route.
  • Activating a phone number for a destination country creates account-scoped SMS routes for that country.
  • A US TEN_DLC or LOCAL number also carries your traffic to the six US territories: Puerto Rico (PR), the US Virgin Islands (VI), Guam (GU), American Samoa (AS), the Northern Mariana Islands (MP), and the US Minor Outlying Islands (UM). Activating it creates a route for each, on the same number. Those routes never fall back to another sender, because a 10DLC number may carry only its own brand's traffic.
  • Where a territory accepts alphanumeric senders, Sent sets one up for your account the first time you send there, before the message routes. It ranks ahead of the 10DLC route and falls back to it, so the alphanumeric sender is tried first and your number is the last resort. Sent never sets one up automatically in the US or Canada, because their carriers don't deliver alphanumeric traffic.
  • Global rules (scoped to no account) apply to all accounts. A send never matches another account's rules.

A rule matches when every dimension it constrains matches the send; a dimension the rule leaves unset matches anything. Rules can constrain the recipient (country, number prefix, exact number, carrier, number type, ported state), the sender, the template (id, name, category), the channel, and whether the send is international.

Matching rules form an ordered candidate list. The ordering criteria, applied in sequence:

  1. Rules pinned to the exact recipient number rank ahead of all others.
  2. Rules scoped to your account rank ahead of global rules.
  3. Match specificity: the share of the send's attributes the rule explicitly matches, highest first.
  4. Rule priority, highest first.
  5. Longer (more specific) recipient number prefix.
  6. Older rule first.

Rules that are inactive, deleted, or expired are excluded, as are rules whose own minimum match threshold is not met. Candidates on a channel where the message's template carries an explicit non-approved review status (for example rejected, pending, or paused) are dropped; a channel with no per-channel review recorded is not blocked.

The first candidate wins: the message transitions to ROUTED, a message.routed webhook fires, and the send dispatches on the winning route. The remaining candidates stay available as fallback routes.

Auto-detect applies no fixed channel preference order among rules. The winner is the best-matching rule under the preceding criteria. However, before rules are ordered, the send's content decides which channels are even eligible: a message with no attachment is ineligible for MMS, and any MMS candidate is removed from its list regardless of rules. See Media and MMS eligibility. If no rule matches, the message fails without a channel; see Messages with channel auto.


Media and MMS Eligibility

Routing cannot see message content, so MMS eligibility is decided before rules are ordered rather than by a rule dimension.

  • A message carrying no attachment is not eligible for MMS on auto-detect. Any MMS candidate is removed from its list, so a text-only send is never billed as MMS, even from an account with an active MMS route.
  • A message with attachments, to a recipient in a covered market, on a template approved for MMS, keeps its MMS candidate. That candidate mirrors the SMS route on the same sender at a higher priority, so auto-detect prefers MMS over SMS on that number.
  • If the market is not covered or the template is not approved for MMS, the candidate is dropped and the message resolves to another channel, usually SMS. An MMS candidate that fails after routing chose it, such as one whose attachment is over 600 KB, falls through the same way.
  • On SMS, the attachment URL is appended to the text as a link when it fits without adding a billed segment. Otherwise the SMS carries the text alone.

This filter only applies on auto-detect. When you name a channel explicitly (channel: ["mms"]), your choice is honored: a text-only pinned MMS is delivered as a carrier MMS with no attachment. The carrier renders it differently from SMS on the handset.

Attachments are supplied per send with media_urls, or carried by the template's mms body (see Template Definition). For the full MMS sending guide, see MMS.


Pinned Channels

A pinned entry (sms, whatsapp, rcs, or mms) restricts matching to routes on that channel. Rules without a channel constraint still match and resolve to the pinned channel.

  • A pinned send never falls back to a different channel. Fallback between routes on the same channel (for example, an SMS provider hop) remains possible when the rule permits it.
  • If no route exists on the pinned channel, the message fails with no route matched, even when another channel could deliver to the recipient.
  • Pinning mms additionally requires allowMms on the account. If the flag is off, the message fails with channel_unavailable rather than falling back to SMS.

Fallback

At Send Time

Fallback walks the resolved candidate list in order:

  • The winning candidate is attempted first. Each attempted route is recorded as a delivery attempt on the same message.
  • If submission to the provider fails and the candidate's rule allows fallback, the next candidate is attempted, repeating down the list.
  • A DENY rule that allows fallback passes the send to the next candidate.
  • A DENY rule that does not allow fallback ends the send as FILTERED with reason_code DELIVERY_004 (internally ERR_ROUTE_DENIED), as does a candidate list in which every route is denied. The message record carries the denied route's channel.

After a Delivery Failure

A message that a provider accepted and later reported as failed can re-enter routing:

  • A terminal FAILED delivery receipt triggers a reroute only when its error signals a route or carrier failure another route might overcome: undeliverable by this route, the carrier refusing the sender itself (for example, a network that doesn't accept alphanumeric senders), no route available to the destination network, provider service unavailable, provider timeout, or a transport error. All other failures stay FAILED, including an invalid number, an unreachable handset, a temporary carrier error, rate limiting, and carrier filtering.
  • Each reroute is a separate send attempt and is charged as one.
  • A WhatsApp message that Meta accepts and then reports as failed for recipient-side reasons is rerouted the same way, and a recipient-scoped rule records that WhatsApp is not deliverable for that number. This is the path behind WhatsApp-to-SMS fallback on auto-detect sends.
  • A reroute excludes every route already attempted and re-runs the send pipeline on the same message id, so the QUEUED and ROUTED transitions and their webhooks fire again.
  • A message attempts at most 3 distinct routes (channel and provider pairs) across its initial send and all reroutes.
  • Consent gates re-apply on every reroute; an opted-out recipient never receives a rerouted message.

Where the Resolved Channel Appears

Internally, a message that has not yet resolved a route carries the placeholder channel auto. Public surfaces expose it as follows:

SurfaceBefore a route is chosenAfter a route is attempted
POST /v3/messages response, recipients[].channelsent for auto-detect entries, otherwise the pinned channelNot updated; the response is returned at accept time
message.queued, message.routed, and message.scheduled webhooks, payload.channelsent for auto-detect sends, otherwise the pinned channelFire again on a reroute
Terminal webhooks (message.sent, message.delivered, message.read, message.failed, message.filtered, message.blocked), payload.channelauto when the send ends before any route was chosenThe channel of the attempted route
GET /v3/messages/{id}, channel fieldauto for auto-detect sends, otherwise the pinned channelThe channel of the attempted route

Webhook payload shapes are documented in Webhook event types; the status lifecycle is documented in Message status tracking.


Messages With Channel auto

A terminal message whose channel is auto ended before routing chose a channel. This occurs only on auto-detect sends; a pinned send keeps its pinned channel in every state.

Terminal statusCausereason_code
FAILEDNo routing rule matched the send: no route covers this recipient for your accountDELIVERY_003
FAILEDRequired template variables missing or invalid (pre-routing validation)VALIDATION_008
FILTEREDPre-routing consent gate: the recipient opted out or the number is on your suppression listBUSINESS_004
BLOCKEDAccount precondition gate: insufficient balance, an onboarding quota, or an unapproved templateBUSINESS_003, BUSINESS_020 or BUSINESS_005

A FAILED message on channel auto with no route matched means the recipient is not covered by any channel that is set up for your account. Routes exist once the corresponding channel setup is complete; see Channel setup. Persistent delivery problems are covered in Messages not delivered.

The reason_code and a reason sentence arrive on GET /v3/messages/{id} and on the message's webhook. See Error handling for how the internal ERR_* codes map to them.

On this page