> ## 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 tenant provisioning lifecycle codes

> One recovery page for the four tenant-lifecycle codes — MISSING_TENANT (400), TENANT_NOT_FOUND (404), TENANT_PROVISIONING (503), and TENANT_SCHEMA_INCOMPLETE (503): how to reproduce the 503-vs-404 split, diagnose a missing org-level tenant record, and route to the right fix.

# Troubleshoot tenant provisioning lifecycle codes

Orbit attaches every authenticated request to your organization's tenant
context before any route runs. When that attachment cannot resolve a usable
tenant, the pre-flight gate rejects the request with one of four lifecycle
codes — and nothing downstream executes.

This page is the recovery hub for the full ladder. Scope it before you
escalate: a 400 `MISSING_TENANT`, a 404 `TENANT_NOT_FOUND`, and a 503
`TENANT_PROVISIONING` all mean different things, and the one code that names
schema drift — `TENANT_SCHEMA_INCOMPLETE` — has its own
[dedicated runbook](/troubleshooting/tenant-schema-incomplete-503).

## The lifecycle ladder

Every organization walks this ladder from signup to steady state. A lifecycle
code tells you exactly where on the ladder the request died:

1. **`MISSING_TENANT` (400)** — the request carried no resolvable tenant
   context at all (no API key header, or an `X-Tenant-Id`-based call with the
   header absent). Attachment never started.
2. **`TENANT_NOT_FOUND` (404)** — the request authenticated, but the resolved
   tenant context points at an organization record that does not exist.
   Attachment started and looked up nobody.
3. **`TENANT_PROVISIONING` (503)** — the organization record exists, but its
   tenant data store is still being initialized (or a stuck initialization is
   queued for the background repair sweep). Attachment found the org and
   found its tenant context not yet ready.
4. **`TENANT_SCHEMA_INCOMPLETE` (503)** — the tenant context is attached, but
   a recently added table migrates in during a rollout — follow the
   [dedicated runbook](/troubleshooting/tenant-schema-incomplete-503) for
   this one code.
5. **Resolved** — the ladder's steady state: the gate passes and the route
   runs.

Codes 1–3 got rejected at the pre-flight gate, so nothing is charged and
nothing is written in any of them.

## Detection

Reproduce with a header-selected request against any tenant-scoped resource
so you can read the raw status split yourself — the 503-vs-404-vs-400
difference is the whole diagnosis:

```bash theme={null}
# In-region call with the header set (should work or fail 503/404):
curl -i https://api.orbit.devotel.io/api/v1/messages \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "X-Tenant-Id: org_your_org_id"

# The same call without the tenant header (should fail 400 MISSING_TENANT):
curl -i https://api.orbit.devotel.io/api/v1/messages \
  -H "X-API-Key: dv_live_sk_your_key_here"
```

Pick the most lightweight tenant-scoped resource your integration already
calls (`GET /api/v1/messages`, `GET /api/v1/contacts`) so the reproduction
costs nothing. Read the `error.code` field of the response — do not parse
the message text:

```bash theme={null}
curl -s https://api.orbit.devotel.io/api/v1/messages \
  -H "X-API-Key: dv_live_sk_your_key_here" | jq -r '.error.code'
```

A `400` narrows to the first rung; a `404` narrows to the second; a `503`
narrows to a provisioning or schema window. That split, plus the envelope's
`meta.request_id`, is what to hand to support.

## Fix per code

### `MISSING_TENANT` (400)

The request never authenticated to a tenant. Send a valid API key (`X-API-Key: dv_live_sk_...`) on API-key flows, or add the
`X-Tenant-Id: <organizationId>` header on internal-header flows. If you see
this *after* the API key resolved (rare), one header consumer in the chain
(access-token exchange, a chained voice/provider hop) dropped the context —
reproduce with the detection curl above and escalate with one `meta.request_id`.

### `TENANT_NOT_FOUND` (404)

The org-level tenant record itself is absent. The two buggy paths that
produce this are a staging window in invited-org onboarding (an invitation
accepts before the org row commits) or a race condition on sub-org creation
(two sibling orgs created concurrently, one row landed incompletely). If you
created the account in the last hour, retry once after a minute. If it
persists, stop retrying and capture the reproduction curl.

On the platform side, Orbit's internal operations team resolves this at the
organization record (Admin Panel → Org → Tenants) — either the row exists
with a wrong tenant reference (repairable in place) or it genuinely does not
exist and onboarding must re-run. The operation concludes with a recovery
scan, a scheduled sweep that re-detects rows whose tenant reference is
missing and queues them for repair. With a paid plan on file, open a support
ticket with your `organizationId` (dashboard → Settings → Organization) and
one failing `meta.request_id`; support routes it to that recovery operation.

### `TENANT_PROVISIONING` (503)

The org exists, but its tenant context is still being initialized. This is
a **transient** gate: provisioning completes in seconds during onboarding,
and when initialization gets stuck (or the request races initialization
under a lock), a background repair sweep re-detects the gap every 15 minutes
and replays it. Unlike `INSUFFICIENT_BALANCE` (402, terminal until funded),
retry with exponential backoff — the window closes on its own. Do **not**
rotate your API key: the key resolved correctly; the 503 fires after
resolution, when attachment finds the context not yet ready. Escalate only
if the same 503 survives past an hour.

### `TENANT_SCHEMA_INCOMPLETE` (503)

A dedicated runbook covers this one — schema drift during a rollout, its
expected duration, and why read endpoints degrade to an empty 200 while
write endpoints 503. See
[Troubleshoot TENANT\_SCHEMA\_INCOMPLETE (503)](/troubleshooting/tenant-schema-incomplete-503).

<Warning>
  Do not pass a `tenant_id` field in a request body to work around any of
  these codes. Server-side tenant resolution derives the context from your API
  key or session, and that server-side resolution is the tenant-isolation
  control Orbit's SOC 2 posture is built on
  ([tenant isolation](/concepts/tenant-isolation), Section 4). Client-supplied
  tenant fields are ignored and cannot point a request at a different context.
</Warning>

## Cross-links

* [TENANT\_SCHEMA\_INCOMPLETE (503)](/troubleshooting/tenant-schema-incomplete-503)
  — the sub-page for the schema-drift rung of the ladder above
* [Error codes reference](/reference/error-codes) — the `MISSING_TENANT`
  row under Tenant / Multi-tenancy and the `TENANT_NOT_FOUND` /
  `TENANT_PROVISIONING` / `TENANT_SCHEMA_INCOMPLETE` rows under System
* [Troubleshooting hub](/reference/troubleshooting-hub) — runbook routing for
  every other error family
* [Auth and API keys](/troubleshooting/auth-and-api-keys) — when the failure
  is the key itself, not tenant attachment
