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

# Troubleshooting: alphanumeric sender ID rejected before send

> Diagnose the pre-send sender-ID gate — SENDER_ID_NOT_REGISTERED, SENDER_ID_NOT_APPROVED, and the transient SENDER_ID_CHECK_UNAVAILABLE — and get a branded alphanumeric sender back to sending.

# Troubleshooting: alphanumeric sender ID rejected before send

Orbit evaluates one alphanumeric-sender gate **before** the message is
accepted for delivery. Send with a branded `from` (for example
`"MyBrand"`) that the account cannot prove, and `POST /api/v1/messages/sms`
rejects the request synchronously — the message is never queued and
never handed to the carrier. Three error codes come out of that gate:
two permanent (fix the sender), one transient (retry).

In the dashboard's compose-SMS dialog the same gate runs client-side:
the send button warns and refuses the submission instead of surfacing
the error after the fact, with a shortcut to sender registration.

## Match the code to its meaning

| Code                          | HTTP | What fired                                                                                                                              | Fix class                                                                              |
| ----------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `SENDER_ID_NOT_REGISTERED`    | 422  | The `from` value is a custom alphanumeric sender ID with **no registration row on the account** for that channel                        | Register the sender ID first — see [Register the sender ID](#register-the-sender-id)   |
| `SENDER_ID_NOT_APPROVED`      | 422  | A registration row exists but its status is `pending`, `rejected`, or `expired` — not `approved`                                        | Wait for approval, do not retry the send — see [Wait for approval](#wait-for-approval) |
| `SENDER_ID_CHECK_UNAVAILABLE` | 503  | The approval lookup itself failed (a transient storage read) and the gate **fails closed** rather than let an unverified sender through | Retry with backoff — see [Retry the check](#retry-the-check)                           |

The first two are always HTTP 422 on the SMS send surface. They are
permanent gates: sending the same request again returns the same code
and burns your rate-limit budget without changing the outcome.

Senders that skip this gate entirely — phone numbers (E.164, MSISDN, or
a short code, whose ownership is proven separately), the fixed platform
default `"Devotel"`, and the shared platform sender pool — never raise
these three codes. The gate applies when you type a **custom
alphanumeric brand** into `from`.

## Reproduce the rejection

Send an SMS with an alphanumeric `from` that is not in the account's
approved sender-ID list:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/messages/sms \
  -H "X-API-Key: dv_live_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+447700900123",
    "from": "MyBrand",
    "body": "Your receipt is ready."
  }'
```

An unregistered sender comes back with HTTP 422 and this body:

```json theme={null}
{
  "error": {
    "code": "SENDER_ID_NOT_REGISTERED",
    "status": 422,
    "message": "Sender ID \"MyBrand\" is not registered for this account. Submit it for approval in Settings → Sender IDs, or pick the platform default (Devotel) / one of your phone numbers.",
    "details": { "sender": "MyBrand", "channel": "sms" }
  }
}
```

A sender that is registered but still under review returns
`SENDER_ID_NOT_APPROVED` with `"status": "pending"` (or `"rejected"` /
`"expired"`) inside `error.details`. When the approval check cannot be
performed at all, the gate fails closed and returns HTTP 503 with
`SENDER_ID_CHECK_UNAVAILABLE`:

```json theme={null}
{
  "error": {
    "code": "SENDER_ID_CHECK_UNAVAILABLE",
    "status": 503,
    "message": "Sender ID approval check for \"MyBrand\" is temporarily unavailable. Retry in a moment, or switch to the platform default (Devotel) sender / one of your registered phone numbers.",
    "details": { "sender": "MyBrand", "channel": "sms" }
  }
}
```

## Fix per code

### Register the sender ID

`SENDER_ID_NOT_REGISTERED` means the value you sent has never been
submitted for the account. Registration is tenant-owned and
self-service:

1. Upload the compliance documents the destination country requires
   (the per-country document list is in
   [Country Compliance Requirements](/compliance/country-requirements)).
2. Submit the sender ID for the destination countries via
   [`POST /compliance/sender-id-registrations`](/compliance/sender-id-registration#register-or-update-a-sender-id),
   or from **Settings → Sender IDs** in the dashboard.
3. Send again once the destination country entry reaches `approved`.

Registration is an idempotent upsert: re-submitting keeps countries
already at `approved` and returns `rejected` / `expired` entries to
`pending` for a fresh review. The full `pending → approved / rejected /
expired` lifecycle is documented on
[Sender-ID Registration](/compliance/sender-id-registration#status-lifecycle).

If you do not need the brand on this send, switch `from` to an owned
phone number or drop it and let the platform default apply — both paths
skip the alphanumeric gate.

### Wait for approval

`SENDER_ID_NOT_APPROVED` means a row exists but has not cleared review.
The `error.details.status` field names the current state:

* `pending` — awaiting review. **Do not retry the send.** Poll the
  entry with
  [`GET /compliance/sender-id-registrations`](/compliance/sender-id-registration#list-your-registrations)
  (or watch **Settings → Sender IDs** in the dashboard) and retry the
  send only after it flips to `approved`.
* `rejected` — the reviewer left a reason on the entry. Fix what it
  names, re-submit (the upsert returns it to `pending`), and wait.
* `expired` — the approval lapsed. Re-submit for a fresh review.

Retrying the send while the status is `pending` never clears the gate —
the send and the registration review are independent, so a retry loop
only re-trips the 422.

### Retry the check

`SENDER_ID_CHECK_UNAVAILABLE` (503) is the transient member of the
family: the gate could not read the approval state and closed rather
than guess. It is safe to retry:

1. Retry the same request after a short backoff (seconds, not
   milliseconds — the check depends on normal service health to
   recover).
2. Use exponential backoff with a retry budget, like the pattern in
   [Troubleshooting: cooldown and rate-limit 429s](/troubleshooting/rate-limits#backoff-code)
   (branch on `res.status === 503` instead of 429).
3. If 503s persist for more than a few minutes, check the
   [status page](https://status.orbit.devotel.io) before treating it as
   a sender problem. A persistent 503 on every sender points at
   platform health, not at your registration.

### Distinguish from the country-specific codes

Brazil, Singapore, Saudi Arabia, and the UAE block unregistered
alphanumeric senders with their own codes —
`MESSAGING_BR_SENDER_NOT_REGISTERED`,
`MESSAGING_SG_SENDER_NOT_REGISTERED`,
`MESSAGING_SA_SENDER_NOT_REGISTERED`, and
`MESSAGING_AE_SENDER_NOT_REGISTERED` — which fire when the destination
country enforces registration even though a status on the account looks
coherent. Those, plus the India DLT regime and the strict-mode
`SENDER_INVALID_FOR_DESTINATION` 422s, are covered on
[Troubleshoot a pending number or Sender ID](/compliance/troubleshooting-pending-gated-surfaces).
The three codes on this page are the **generic gate**: they fire on any
destination, before any country rule runs.

## Escalation

Escalate to support when you have done the fix above and it cannot
land — a registration stuck at `pending` well past the country's normal
lead time, a `rejected` reason you cannot resolve with the documents
you hold, or 503s that outlast a status-page window. Include:

1. The **sender ID value** (exactly as sent in `from`) and the
   **destination country**.
2. The **sender-ID registration state** — copy the entry's current
   status from **Settings → Sender IDs** or
   `GET /compliance/sender-id-registrations`.
3. The **message ID or request ID** from a rejected send (`error` code
   and `meta.request_id`), and the timestamp with timezone.

A reviewer can pull the registration packet and the send attempt
directly from those three.

## Related references

* [Sender-ID Registration](/compliance/sender-id-registration) — the registration endpoints and the `pending → approved` lifecycle.
* [Country Compliance Requirements](/compliance/country-requirements) — per-country sender rules and required documents.
* [Troubleshoot a pending number or Sender ID](/compliance/troubleshooting-pending-gated-surfaces) — the country-specific registration codes and India DLT.
* [Error Codes](/reference/error-codes) — the full sender-registration error table.
