Troubleshoot sender-ownership 422s
Numeric senders pass through a hard pre-send ownership gate. When the E.164 number you named infrom belongs to a different organization on
the platform, the send is refused before it ever reaches a carrier — the
Devotel softswitch trusts the originator field, so without this fence a
recipient would see (and attribute the message to) the true owner’s
number. The gate returns 422 SENDER_NOT_OWNED, and when it cannot
confirm ownership because of a transient database or cache fault it
refuses the send with 503 SENDER_OWNERSHIP_CHECK_UNAVAILABLE instead.
Both are pre-send rejects: no message is submitted and no message charge
is taken.
Match the code to its meaning
The distinction drives the fix:
SENDER_NOT_OWNED is a sender fix —
retrying the identical payload returns the same 422 forever. The 503
sibling is a transient platform state — retry the same request after a
short backoff (about 30 seconds, with jitter).
SENDER_NOT_OWNED fires only on cross-organization collisions. Sending
from a fully custom number that your organization does not own and that
no other organization holds produces a different flow. The deliberate
trigger list:
- Cross-org number — hard reject.
- Stale tenant number — your org once held the number, then released it and another organization claimed it. Released inventory stays selectable in older dashboards or hard-coded apps, so sends from it start failing here.
- Softphone direct number — an extension’s assigned caller ID that is no longer in your inventory is rejected on the same code when an agent texts from that extension.
Fix the 422 — pick a sender you own
The gate accepts any sender identity your organization legitimately controls. Apply one of these once, then retry the send:- Send from a number you own. List active inventory with
GET /api/v1/numbersand pass one of those E.164 numbers infrom. A number you purchased or ported in passes with no extra step. - Verify an external number through the register → confirm flow.
If your own handset or landline must appear as the sender, enrol it
once and the gate accepts it afterwards:
- Register —
POST /api/v1/voice/caller-ids/verifywith the E.164phone_numberand thechannel("sms"or"voice"). Orbit sends a one-time code to that handset (a text on SMS, spoken readback on voice). - Confirm —
POST /api/v1/voice/caller-ids/confirmwith theverification_idand the code. A correct code flips the row toverifiedand opens the number as an outbound sender. - A wrong code or an elapsed TTL leaves the row
expired; re-arm it withPOST /api/v1/voice/caller-ids/:id/resendand confirm again. The full endpoint contract is in Manage outbound caller IDs, and the same journey runs from the dashboard under Voice → Caller IDs.
- Register —
- Use the platform default. Omit
from(or omit the pool) and the resolution chain falls back to the shared(Devotel)sender — see Sender resolution. Alphanumeric sender IDs registered to your organization skip the numeric ownership lookup entirely, subject to destination-country alpha rules (US/Canada carriers reject alphanumeric senders outright — send to those destinations from a number).
Why the 503 fails closed
An ownership check that errors rather than answering has a choice: pass the send along without an ownership verdict, or refuse it. The gate refuses it. Passing along would let a momentary datastore or cache outage quietly disable the only control that stops one organization from sending under another organization’s number — recipients would see the wrong number, and carrier complaints would land on the true owner. A brief 503 that a retry clears is cheaper than that, so the gate treats “cannot confirm ownership” the same as “ownership denied”: the send is refused until the check works again. If 503s persist beyond a few minutes: check status.orbit.devotel.io, then retry through your normal idempotent retry path. The 503 is safe to retry — the send was never submitted, and re-sending with the same idempotency key cannot duplicate a message.Sample error envelopes to paste into a ticket
Cross-org numeric sender,POST /api/v1/messages/sms:
error object, the
endpoint, and the timestamp — the sender and channel fields in
details are what support needs to trace the gate decision.
Related references
- Sender resolution — the precedence chain that picks a sender when the request names none.
- Troubleshoot sender resolution and pool errors —
the sibling codes
SENDER_REQUIRED,SENDER_POOL_NOT_FOUND, andNO_SENDER_CONFIGURED. - Fix an empty sender pool — the pool 422 that resolves but has no members.
- Manage outbound caller IDs — the register → confirm journey and lifecycle states.
- Error codes — the full send-gate error table.