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

# Fix an empty sender pool (`SENDER_POOL_EMPTY`)

> A routed sender pool resolved fine but has zero members, so the send is rejected with 422 before anything is queued. Here is how to confirm and fix it.

# Fix an empty sender pool (`SENDER_POOL_EMPTY`)

`SENDER_POOL_EMPTY` is a deterministic, pre-send rejection: your request
named a valid pool, Orbit looked up the pool, and found it has no members
to draw a sender from. The send never reaches a provider, so nothing to
retry — add a member to the pool (or route through a different pool) and
send again.

## Symptoms

* The send request returns HTTP 422 with code `SENDER_POOL_EMPTY`, and
  the response names the pool that was empty.
* The dashboard **Delivery Log** shows no row for the message — the send
  was rejected before queueing, so there is nothing to deliver.
* The pool's detail page prompts you to add a DID, and the senders list
  for the pool is empty.

An identical 422 also comes back from the pool preview endpoint
(`GET /api/v1/messaging/sender-pools/{id}/preview`) when the pool has no
members, so the symptom surfaces before you send real traffic if you
preview first.

## Causes

The pool row exists and resolves — the failure is membership:

* The pool's `sender_dids` list has no entries. Two ways a pool reaches
  that state: it never had members (created with an empty list and never
  filled, or the last member was removed), or the send carried a
  narrower recipient filter and none of the pool's members were
  eligible, leaving zero candidates for that recipient.
* A messaging service, campaign, or sender
  [routing rule](/guides/sms-services) still points at the pool, so
  every send routed through it fails with the same code.

## Fix: put a sender in the pool

Either fix the pool itself, or route the send elsewhere — tenant-owned
controls only.

1. **Add at least one member to the pool.** A pool member can be an
   E.164 DID, a numeric short code, or an alphanumeric sender ID —
   update the pool with
   `PATCH /api/v1/messaging/sender-pools/{id}` and set `sender_dids`,
   or add the sender in the dashboard's pool editor. Make sure the
   sender is one your organisation actually owns:
   `GET /api/v1/numbers` lists the DIDs on your organisation before you
   send.
2. **Route through a pool that has members.** Pass a different
   `sender_pool_id` on the request, or repoint the wiring that led here
   — a messaging service's default pool, a campaign, or a routing rule —
   at a non-empty pool.
3. **Retry the send.** `SENDER_POOL_EMPTY` is rejected before any
   pick is made, so no selection state was written for the
   recipient — the retry routes cleanly, and the same idempotency key
   resubmits without a duplicate.

## Distinguish it from the neighbouring codes

| Code                                                                 | HTTP | What fired                                                                                                      | Fix                                                     |
| -------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| `SENDER_POOL_EMPTY`                                                  | 422  | The pool **exists** but has no members                                                                          | Add a member to the pool, or route through another pool |
| [`SENDER_POOL_NOT_FOUND`](/troubleshooting/sender-resolution-errors) | 404  | The pool id names **no pool at all** — a wrong or deleted id                                                    | Verify the id, or re-create the pool                    |
| [`NO_SENDER_CONFIGURED`](/troubleshooting/sender-resolution-errors)  | 422  | No pool was named, and your organisation has **no sender anywhere** — no default sender, no active phone number | Register a sender first                                 |

The telling difference: `SENDER_POOL_EMPTY` is pool-level state (a good
pointer, an empty list), `SENDER_POOL_NOT_FOUND` is the pointer itself
(there is no pool), and `NO_SENDER_CONFIGURED` is organisation-level
state (no sender of any kind yet).

## Example envelope

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

returns HTTP 422:

```json theme={null}
{
  "error": {
    "code": "SENDER_POOL_EMPTY",
    "status": 422,
    "message": "Sender pool pool_emptypool has no DIDs configured"
  }
}
```

## Related references

* [Sender pools](/guides/sender-pools) — create pools, add members, and
  understand selection strategies.
* [Sender resolution](/concepts/sender-resolution) — where the pool pick
  sits in the full precedence chain.
* [Troubleshoot sender resolution and pool errors](/troubleshooting/sender-resolution-errors)
  — the three sibling codes (`SENDER_REQUIRED`, `SENDER_POOL_NOT_FOUND`,
  `NO_SENDER_CONFIGURED`).
* [FAQ: Why did my send return `422 SENDER_POOL_EMPTY`?](/reference/faq)
  — the one-line version of this page.
* [Error codes](/reference/error-codes) — the full sender error table.
