> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# How routing picks a sender

> The precedence chain Orbit follows to choose a sender at send time: explicit from, from_extension, sender pools, messaging-service defaults, sticky inbound sender, and the fallback chain — plus how inbound rules route replies.

# How routing picks a sender

When you send a message without hardcoding a sender, Orbit resolves the `from` address through a fixed precedence chain. This page documents that chain, what each sender-pool strategy does, and how inbound (MO) rules route replies. Request and response schemas are owned by the [Messaging API reference](/api-reference/endpoints/messaging); this page covers routing behaviour only.

## Precedence: what the platform checks first

On `POST /api/v1/messages/sms`, Orbit resolves the sender in this order. The first source that produces a sender wins:

| # | Source                               | Wins over                                                         | Notes                                                                                                                                                                                                           |
| - | ------------------------------------ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `from_extension`                     | Everything below                                                  | UCaaS per-user business SMS — resolves to the DID on that extension. Mutually exclusive with `sender_pool_id` (sending both returns 422)                                                                        |
| 2 | `sender_pool_id` in the request body | A bare `from`, messaging-service defaults, and the fallback chain | Resolved through the pool's strategy (below). Sending both `from` and `sender_pool_id` is an ambiguous request — the pool wins and the explicit `from` is ignored; pass exactly one sender identity per request |
| 3 | `from` in the request body           | Messaging-service defaults and the fallback chain                 | An explicit sender is the operator's choice — honoured when no pool id is on the body                                                                                                                           |
| 4 | `messaging_service_id`               | Conversation sticky sender and the fallback chain                 | The service's own `sender_pool_id` (or per-country override pool) fills in **only** when you did not pass `sender_pool_id` yourself                                                                             |
| 5 | Conversation sticky sender           | Fallback chain                                                    | Two-way SMS replies to an existing conversation pin the sender to the DID the contact originally texted — only when no source above matched                                                                     |
| 6 | Fallback chain                       | —                                                                 | Org default sender → your first active number → the platform default number for `+1` destinations, or the `Devotel` alphanumeric sender ID for international destinations                                       |

Three rules worth knowing up front:

* `sender_pool_id` and `from_extension` are mutually exclusive; sending both returns `422`.
* Sending both `from` and `sender_pool_id` is an ambiguous request — the pool wins and the explicit `from` is silently ignored. Pass exactly one sender identity per request (the full interaction matrix is on [Sender resolution](/concepts/sender-resolution)).
* On a messaging service with a `country_sender_pools` map, the recipient-country's override pool is preferred before the service-level default pool — but only when you did not set `sender_pool_id` explicitly.

## Sender pool resolution

A sender pool groups sender identities (E.164 numbers, short codes, alphanumeric sender IDs) behind a selection strategy. At send time the pool picks exactly one of its members:

| Strategy           | How it picks                                                         | Where the state lives                                                                                  |
| ------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `sticky` (default) | Deterministic per-recipient pick                                     | The per-recipient assignment is persisted so the same recipient keeps the same sender across restarts  |
| `round_robin`      | Cycles through pool members in order                                 | A per-pool counter spreads volume evenly                                                               |
| `random`           | Uniform pick                                                         | No state                                                                                               |
| `geomatch`         | Matches the recipient's country to a same-country sender in the pool | Falls back to `sticky` over the whole pool when no sender matches the country, so the send never fails |

Each pool member accumulates a health tier from delivery outcomes, and the rotation scheduler auto-swaps a degraded member for a warmed replacement. Creating pools, previewing which sender a recipient would get, and reading health are covered in the [Sender pools guide](/guides/sender-pools).

## Inbound routing (MO)

Outbound picks a sender; inbound rules decide where a received message goes. Tenant-level inbound rules are evaluated in priority order (lower value first) and match on:

* `number` — the destination DID the message arrived on
* `sender` — the originating address
* `keyword` — case-insensitive substring of the message body
* `regex` — a regular expression tested against the body

The first enabled rule that matches dispatches to one of: a `webhook` (signed HTTPS POST), a `queue`, an `inbox`, a `team`, or an `ivr` keyword menu tree. When no rule matches, the message falls through to the default inbox and the `message.received` event. Manage rules under `/api/v1/messages/inbound-routes`.

This tenant-level rule set sits above the per-DID inbound hooks you may also have configured: pools own the "which sender" decision, these rules own the "where the reply lands" decision.

## One curl example per branch

Explicit sender (branch 1):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155550100", "from": "+14155559999", "body": "Hi" }'
```

Sender pool (branch 3):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155550100", "sender_pool_id": "pool_abc123", "body": "Hi" }'
```

Messaging service fallback (branch 4 — the pool comes from the service):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "to": "+14155550100", "messaging_service_id": "ms_abc123", "body": "Hi" }'
```

Inbound rule (MO):

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/inbound-routes \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "VIP replies to the priority inbox",
    "matchType": "keyword",
    "matchValue": "vip",
    "targetType": "inbox",
    "targetConfig": { "inboxId": "inbox_vip" },
    "priority": 10
  }'
```

For the full request/response schema of the send endpoint, see the [Messaging API reference](/api-reference/endpoints/messaging).

## See also

* [Sender pools guide](/guides/sender-pools) — create pools, preview picks, read health
* [Messaging credentials & services](/api-reference/messaging-credentials) — attach a pool as a service's sending identity
* [Send and receive messages](/guides/send-receive-messages) — end-to-end walkthrough
