> ## 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.

# Troubleshoot sender resolution and pool errors

> Decode `SENDER_REQUIRED`, `SENDER_POOL_NOT_FOUND`, and `NO_SENDER_CONFIGURED` — the three codes Orbit raises when an outbound send cannot resolve a sender — and fix each in minutes.

# Troubleshoot sender resolution and pool errors

Every outbound message needs a sender, and Orbit checks for one before it
accepts the send. Three error codes cover the whole failure family: the
request named no sender at all, the request pointed at a pool that does
not resolve, or your organisation has no usable sender on file. Match the
code to its meaning before you retry — these are permanent rejects, so a
blind retry loop returns the same code.

## Match the code to its meaning

| Code                    | HTTP | What fired                                                                                                                           | Fix class                                    |
| ----------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------- |
| `SENDER_REQUIRED`       | 422  | The send body carried **no sender selector at all** — no `from`, no `sender_pool_id`, and no `messaging_service_id`                  | Name one selector on the request             |
| `SENDER_POOL_NOT_FOUND` | 404  | The body carried a `sender_pool_id`, but it points at a pool that does **not exist** on your organisation                            | Verify the target pool's id, or re-create it |
| `NO_SENDER_CONFIGURED`  | 422  | The fallback chain was consulted and your organisation has **no sender to fall back to** — no default sender, no active phone number | Register a sender, then retry                |

`SENDER_REQUIRED` is a request-shape problem — fix the payload. The other
two are organisation state: the pool pointer or the sender inventory. A
retry without the matching fix burns rate-limit budget and re-enqueues
the same code.

## Fix per code

### `SENDER_REQUIRED` — the request named no sender

A send body must carry at least one sender selector. Sending without any
of them:

```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",
    "body": "Order shipped"
  }'
```

returns HTTP 422:

```json theme={null}
{
  "error": {
    "code": "SENDER_REQUIRED",
    "status": 422,
    "message": "A sender is required. Provide `from` (a claimed number, sender ID, or the shared-generic sender), `sender_pool_id`, or `messaging_service_id`. Direct API sends must declare a sender so a message is never sent from an ambiguous identity."
  }
}
```

Fix by adding one selector — only one of these needs to be present:

* `from` — a number you own, a registered alphanumeric sender ID, or the
  shared platform sender.
* `sender_pool_id` — a pool the send rotates across.
* `messaging_service_id` — a service whose default pool supplies the
  sender.

A whitespace-only `from` (for example `""`) counts as omitted and trips
the same code, so an empty-string fallback does not satisfy the gate.
The full precedence chain — a pool beats a bare `from`, and a
`messaging_service_id` fills in only when you named neither — is on
[Sender resolution](/concepts/sender-resolution).

### `SENDER_POOL_NOT_FOUND` — the pool pointer does not resolve

This request names a pool, but the id does not resolve to a pool row on
your organisation:

```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_deleted00",
    "body": "Order shipped"
  }'
```

returns HTTP 404:

```json theme={null}
{
  "error": {
    "code": "SENDER_POOL_NOT_FOUND",
    "status": 404,
    "message": "Sender pool pool_deleted00 not found"
  }
}
```

Two fixes, depending on what you want:

* **Point at a real pool.** List your pools with
  `GET /api/v1/messaging/sender-pools`, copy the id of the pool you
  meant, and send again. The full endpoint table, including preview and
  health reads, is in the [Sender pools guide](/guides/sender-pools).
* **Drop the pool.** Pass `from` alone, or pass `sender_pool_id` and let
  a different pool resolve. If the pool was deleted, any wiring that
  still points at it — a messaging service's default pool, a
  `country_sender_pools` entry — will keep hitting this 404 until you
  repoint it.

A pool that exists but has no senders fails differently —
`422 SENDER_POOL_EMPTY` — and is not this code.

### `NO_SENDER_CONFIGURED` — the organisation has no sender to fall back to

When a send reaches the fallback chain — an inbox conversation without a
sticky sender, a campaign send, or a double-opt-in confirmation prompt —
and the chain is the only place a sender could come from, your
organisation must already own one. With no default sender and no active
phone number, the send rejects with HTTP 422:

```json theme={null}
{
  "error": {
    "code": "NO_SENDER_CONFIGURED",
    "status": 422,
    "message": "No sender configured. Please select a sender ID, claim a trial number, or purchase your own number."
  }
}
```

Fix by registering a sender — pick any of these, then resend:

1. Register an alphanumeric sender ID — see
   [Sender-ID registration](/compliance/sender-id-registration).
2. Claim or purchase a phone number — see
   [Phone numbers](/numbers/overview).
3. Set an organisation default sender for the channel so the fallback
   chain always has one to pick.

Campaign sends and double-opt-in prompts reach this same guard on the
send pipeline, so the scan you do here covers those surfaces too.

## Reconcile the three codes

| Code                    | The request named...               | The organisation has...                            | Your move                                   |
| ----------------------- | ---------------------------------- | -------------------------------------------------- | ------------------------------------------- |
| `SENDER_REQUIRED`       | no sender at all                   | any sender configuration                           | Add one selector to the request body        |
| `SENDER_POOL_NOT_FOUND` | a `sender_pool_id`                 | the pool that id points at (missing)               | Verify the id, or pass a different selector |
| `NO_SENDER_CONFIGURED`  | a sender failure path fell through | zero usable senders (no default, no active number) | Register a sender, then retry               |

The distinction matters: `SENDER_REQUIRED` is always a request fix,
`SENDER_POOL_NOT_FOUND` is a pointer fix, and `NO_SENDER_CONFIGURED` is
a one-time setup fix.

## Related references

* [Sender resolution](/concepts/sender-resolution) — the full precedence
  chain: pool over bare `from`, `messaging_service_id` fills in only when
  you named neither, and the fallback order.
* [Sender pools](/guides/sender-pools) — create pools, preview picks, and
  read per-member health.
* [Error codes](/reference/error-codes) — the full sender-resolution
  error table.
