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

# Tenant-side KYC submission and renewal runbook

> Walk a compliance profile from document upload through submission, review, and approval, then keep it alive — the four destinations that consume it, the document-reuse matrix, the renewal window, and the failure-mode pointer table.

# Tenant-side KYC submission and renewal runbook

The two sibling pages in this group define the objects —
[KYC Documents & the Compliance-Profile Lifecycle](/compliance/documents-kyc)
covers the upload mechanics, and
[The KYC identity model](/compliance/kyc-identity-model) defines the
document → profile → destination triangle. This page is the *runbook*:
the order you work them in, from first submission through review and
approval, the destinations that consume the approved profile, and the
renewal loop that keeps it from expiring under you.

All endpoints below are rooted at
`https://api.orbit.devotel.io/api/v1/compliance`.

<Note>
  Compliance posture is tenant-owned. You assemble the profile, submit
  it, and choose the destinations it backs; Orbit enforces the lifecycle
  gates and carries the packet to the reviewer. Final approval always
  comes from the carrier or regulator — the platform never approves its
  own packet.
</Note>

***

## 1. What a compliance profile is

A **compliance profile** (`cprof_…`) is one regulatory identity bundle:
who the end user is, for which `use_case`, in which country, backed by
documents from your library. Carriers review the profile as a unit —
approve it once and every destination referencing its id inherits the
approval. The alternative is a per-destination packet: one bundle for
numbers, another for Sender IDs, another for 10DLC — several review
queues, several renewal calendars, and several chances for a document
to lapse on one surface while the others still work. Keep scope
deliberate: a shared profile funnels its destinations through one
review and one expiry clock, so most tenants run a handful of
narrowly-scoped profiles rather than one global one.

A profile moves through one fixed lifecycle, with three side-exits:

```
draft → pending_review → approved → expired
           │                 │
           ├─ rejected       └─ rejected
           └─ partially_rejected
```

Only `draft`, `rejected`, and `partially_rejected` are editable;
everything else is frozen so the copy carriers hold and the copy Orbit
reads stay in sync. The state-by-state map is on
[Compliance profile lifecycle errors](/compliance/compliance-profile-lifecycle-errors).

The full end-to-end pattern this frame reuses — attach-by-id, rotation
without downtime, and the first-launch checklist — is on
[Assemble a Shared Compliance Profile Across Gated Surfaces](/compliance/compliance-profile-assembly).

<Note>
  The once-per-workspace organization review (the dashboard banner that
  gates sending) is a separate gate from this per-destination packet —
  see [Organization KYC onboarding](/guides/organization-kyc-onboarding).
  An approved organization does not settle a destination's profile, and
  vice versa.
</Note>

***

## 2. The four destination types that consume the profile

Every gated surface that consumes an approved profile falls into one of
four destination classes. Decide which of them you are opening before
you create the profile — the `use_case` you set is the gate it answers
to.

| Destination class | `use_case` | Console surface |
| - | - | - |
| Phone numbers in regulated markets | `phone_number_purchase` | Numbers |
| Alphanumeric Sender IDs | `sms_sender_id_alphanumeric` | Settings → Compliance → Sender IDs |
| US 10DLC brand / campaign drafts | `sms_10dlc_brand_us` / `sms_10dlc_campaign_us` | Settings → Compliance → Brand identity |
| WhatsApp Business Account (WABA) | `whatsapp_business_verification` | Channels → WhatsApp |

Pass the id explicitly at attach time — an explicit
`compliance_profile_id` beats any surface's auto-pick:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/numbers/purchase \
  -H "Authorization: Bearer $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "country_code": "DE",
    "type": "local",
    "compliance_profile_id": "cprof_abc123"
  }'
```

The gate opens only on `approved`; any other status answers the same
422 as a missing profile. The ten-value `use_case` reference (RCS,
email, voice, and the fallback `other`) is on
[Compliance-profile use cases](/compliance/compliance-profile-use-cases).

***

## 3. Combo coverage matrix — which use-cases reuse which documents

Documents live in a tenant-wide library; the same `doc_…` id backs as
many destinations as accept it, possibly in a different role per
profile. The matrix below shows which uploaded documents each
destination class typically consumes — reuse works when the role and
country line up:

| Destination class | `business_doc` | `address_proof` | `id_proof` | `authorization` |
| - | :-: | :-: | :-: | :-: |
| Numbers provisioning (`phone_number_purchase`) | ✓ | ✓ | ✓ | when an agency files for a brand |
| Sender-ID registration (`sms_sender_id_alphanumeric`) | ✓ | per country | per country | when an agency files for a brand |
| 10DLC brand / campaign (`sms_10dlc_brand_us` / `…_campaign_us`) | ✓ | — | — | — |
| WABA (`whatsapp_business_verification`) | ✓ | per Meta's ask | per Meta's ask | brand authorization |

"Per country" is literal — Germany wants address proof much more often
than the US does, and the fallback `other` role catches what the four
named roles do not. Check the destination market's packet on
[Country Compliance Requirements](/compliance/country-requirements)
before you upload, and run
[regulatory preview](/numbers/regulatory-preview) to settle the exact
fields and documents a country requires.

The practical play: upload a document once, then attach its `doc_…` id
to every profile that accepts it. A German business registration can
back your DE number profile today and your Sender-ID filing tomorrow
with no second upload.

***

## 4. Renewal runbook — open the re-execution window early

Renewal is always a fresh upload plus a re-reference — never an edit in
place — and it is cheapest *before* the clock lands. Two clocks drive
two runbooks:

**Document expiry (the common case).** Orbit derives per-number alerts
from each attached document's `expires_at` and the carrier verify-by
deadline, served on `GET /numbers/document-expiry-alerts` and mirrored
by the **expiry-alerts banner on the dashboard's Numbers page**. The
look-ahead window defaults to 30 days; set
`numbers.document_expiry_alert_days` (1–365) to 60 when your renewal
lead time needs a 60-day re-execution window, so a replacement packet
is in review while the current one still backs traffic.

1. Alert fires with `suggested_action: renew` — still inside the
   window, no gate has fired.
2. Upload the replacement first
   (`POST /compliance/documents`) — renewal returns a **new** `doc_…`
   id, not a version of the old one.
3. Re-reference it on every consumer of the old id: each affected
   profile (same role), each Sender-ID country entry (idempotent
   upsert keeps approved approvals), each open 10DLC draft.
4. Detach the expired document, then `DELETE /compliance/documents/:id`
   once nothing references it — a refused delete is your completeness
   check.

**Profile validity expiry.** When the profile's own validity window
closes (`expired`), the destination keeps the attachment but the
backing stops counting. Clone the frozen profile, fix and submit the
clone, re-attach downstream, then detach and delete the old profile —
the old one keeps serving traffic while its replacement clears review,
so a swap is never a gap. The full rotation order is on
[Assemble a Shared Compliance Profile](/compliance/compliance-profile-assembly).

Renew inside the window and the destination keeps its approved backing
while the replacement is under review — you never enter a gated state.
Renew after the lapse and the surface is gated until the reviewer
approves the new packet.

***

## 5. Failure modes — which code to chase

When the chain breaks, the symptom lands on the destination. Route by
the error you have:

| Symptom / error code | What it means | Owning runbook |
| - | - | - |
| `COMPLIANCE_PROFILE_REQUIRED` (422) | No approved profile references this destination | [Compliance profile lifecycle errors](/compliance/compliance-profile-lifecycle-errors) |
| `COMPLIANCE_PROFILE_NOT_APPROVED` (422) | The referenced profile is `draft`, `pending_review`, `rejected`, or `expired` | [Compliance profile lifecycle errors](/compliance/compliance-profile-lifecycle-errors) |
| `COMPLIANCE_PROFILE_LOCKED` (409) on edit / attach / submit | The profile left `draft`; mutation is frozen | Clone-and-fix on [lifecycle errors](/compliance/compliance-profile-lifecycle-errors) |
| `COMPLIANCE_PROFILE_IN_USE` (409) on delete / document-detach | A downstream asset still references the profile | Detach walk on [lifecycle errors](/compliance/compliance-profile-lifecycle-errors) |
| `SENDER_ID_NOT_APPROVED` | The Sender-ID registration lapsed past its approval | [Troubleshoot pending gated surfaces](/compliance/troubleshooting-pending-gated-surfaces) |
| Regulatory preview flips `compliance_profile_satisfies: false` on a complete profile | An attached document's `expires_at` passed — it stops counting the moment it lapses | Section 4 above |
| A number stuck at `pending_compliance` | Attached but not yet approved, or the carrier verify-by deadline is running | [Troubleshoot pending gated surfaces](/compliance/troubleshooting-pending-gated-surfaces) |

The gate never lies about *which* object lapsed — renew the document
first, the profile reference second, and the destination resubmission
last.

***

## Related references

* [KYC Documents & the Compliance-Profile Lifecycle](/compliance/documents-kyc) —
  the upload, role, and expiry mechanics this runbook sequences.
* [The KYC identity model](/compliance/kyc-identity-model) — the
  document → profile → destination triangle defined.
* [Assemble a Shared Compliance Profile Across Gated Surfaces](/compliance/compliance-profile-assembly) —
  the reuse pattern and rotation order this runbook reuses.
* [Compliance profile lifecycle errors](/compliance/compliance-profile-lifecycle-errors) —
  the four profile codes with the unblocked path for each.
* [Compliance-profile use cases](/compliance/compliance-profile-use-cases) —
  the ten `use_case` values beyond the four destination classes above.
* [Organization KYC onboarding](/guides/organization-kyc-onboarding) —
  the once-per-workspace review the dashboard banner tracks.
* [Country Compliance Requirements](/compliance/country-requirements) —
  which documents each market asks for before you upload anything.
* [API Reference → Compliance](/api-reference/endpoints/compliance) —
  the endpoint surface, including the clone endpoint rotation drives.
