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

# KYC Documents & the Compliance-Profile Lifecycle

> Upload KYC documents once, reference them by doc_… ID across compliance profiles and Sender-ID registrations, and renew them before they age out and block your numbers.

# KYC Documents & the Compliance-Profile Lifecycle

Regulated markets don't accept "trust me" — a carrier or regulator wants
proof of who you are before it lets a phone number activate or a Sender ID
carry traffic. Orbit models that proof as two things you own: a **document
library** (the files themselves) and **compliance profiles** (the structured
identity the documents back up). This page explains what a profile captures,
how documents move from upload to reuse to renewal, where the same document
gets referenced, and how to see an expiry coming before it costs you a
number.

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

<Note>
  Orbit stores your documents, carries them to the carrier, and surfaces
  their review status — **final approval is always granted by the carrier or
  regulator in each country**, not by the platform. Supplying and renewing
  the documents themselves stays with you.
</Note>

***

## 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. Carriers review the
profile as a unit — approve it once and every number or sender that profile
covers can use it.

| Field                        | What it captures                                                                                                                                                                                                                                                              |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                       | Your label for the profile, e.g. "DE local numbers — Acme GmbH".                                                                                                                                                                                                              |
| `use_case`                   | What the identity is for: `phone_number_purchase`, `sms_sender_id_alphanumeric`, `sms_10dlc_brand_us`, `sms_10dlc_campaign_us`, `sms_tfv_us`, `whatsapp_business_verification`, `rcs_brand_verification`, `email_domain_verification`, `voice_carrier_kyc`, `other`.          |
| `country_code` / `countries` | The market(s) the profile answers to. Required for phone-number and Sender-ID use cases; optional for country-agnostic ones (WhatsApp, RCS, email).                                                                                                                           |
| `end_user_type`              | `business` or `individual` — regulators apply different document rules to each.                                                                                                                                                                                               |
| structured data              | The typed fields the country asks for (registered business name, address, tax ID, …) set via `PUT /compliance-profiles/:id/data`. Check exactly which fields a country requires with the [regulatory-preview endpoint](/numbers/regulatory-preview) before you start filling. |

A profile's own status moves `draft` → `pending_review` → `approved` (or
`rejected` / `partially_rejected`), and to `expired` when its validity
window closes. Only an `approved` profile satisfies a country's checks.

***

## The document lifecycle

Documents live in a tenant-wide **library**, separate from any single
profile. Upload a passport once and you can attach it to a German
phone-number profile today and reuse the same file for a Sender-ID
registration tomorrow — no second upload.

### 1. Upload

`POST /compliance/documents` takes a `multipart/form-data` upload and
returns the document's library ID, which always starts with `doc_`:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/documents \
  -H "Authorization: Bearer $ORBIT_API_KEY" \
  -F "type=business_registration" \
  -F "country_code=DE" \
  -F "file=@/path/to/registration.pdf"
```

| Accepted       | Values                                                                                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Document types | `id_card`, `passport`, `drivers_license`, `utility_bill`, `bank_statement`, `business_registration`, `vat_certificate`, `lease_agreement`, `proof_of_address`, `power_of_attorney`, `other` |
| File formats   | JPEG, PNG, WebP, PDF                                                                                                                                                                        |
| Max size       | 10 MB                                                                                                                                                                                       |

Files are encrypted before they leave the API and held in private storage;
nothing about a `doc_…` ID is guessable or shareable outside your
organization. List the library any time with `GET /compliance/documents`.

### 2. Reference by `doc_…` ID

A document by itself is inert — it does regulatory work only when it is
**attached to a profile** with a role:

```bash theme={null}
curl -X POST https://api.orbit.devotel.io/api/v1/compliance/compliance-profiles/cprof_abc123/documents \
  -H "Authorization: Bearer $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "document_id": "doc_k7f2m9x1ab", "role": "business_doc" }'
```

Roles (`id_proof`, `address_proof`, `business_doc`, `authorization`,
`other`) tell the carrier which requirement the document satisfies. The
same `doc_…` ID may play a different role in a different profile.

### 3. Expiry

Many regulators treat documents as stale after a fixed age — UK Ofcom,
Germany's BNetzA, and France's ARCEP, among others, generally require ID or
address proof to be no older than 3–12 months. Orbit records an `expires_at`
per attached document; once a document lapses, it stops counting toward the
country's requirements even while the file itself is still in your library.

### 4. Renewal

Renewing is a fresh upload, not an edit: upload the replacement document,
attach it to the profile in the same role, then detach (and optionally
delete, with `DELETE /compliance/documents/:id`) the expired one. Profiles
already `approved` stay approved while you swap the document — the
submission is re-reviewed on next use.

<Warning>
  Deleting a document is refused while it is still attached to any profile.
  Detach it from every profile first, then delete.
</Warning>

***

## Where documents are reused

The `doc_…` ID is the single pointer three product surfaces share:

1. **Sender-ID registration.** Each country entry in
   [Sender-ID Registration](/compliance/sender-id-registration) carries
   `document_refs`: a list of `doc_…` IDs backing that country's filing.
   The registration route never accepts files — reference the library IDs
   you already uploaded, and the same document backs as many countries as
   accept it.
2. **Numbers regulatory preview.** The
   [regulatory-preview](/numbers/regulatory-preview) check returns
   `compliance_profile_satisfies: true` only when a profile covers every
   required field **and** its attached documents are non-expired — an
   expired document flips the flag to `false` even on an otherwise complete
   profile.
3. **Number purchase gating.** Buying a number in a regulated country
   without a satisfying profile lands the number at `pending_compliance`:
   it's debited, but it won't activate until an approved profile is
   attached. If the carrier's verify-by deadline passes while the number is
   still waiting, the number can be auto-released — see
   [Number Lifecycle](/numbers/lifecycle) for release and recovery.

***

## Monitor expiry before it costs you a number

Orbit derives per-number expiry alerts from the timestamps it already
stores: each document's `expires_at`, and the carrier verify-by deadline on
numbers waiting at `pending_compliance`. Read them with:

```bash theme={null}
curl "https://api.orbit.devotel.io/api/v1/numbers/document-expiry-alerts" \
  -H "Authorization: Bearer $ORBIT_API_KEY"
```

Every alert names the number, the soonest binding expiry
(`earliest_expiry_at`), whether it came from a document or the carrier
deadline (`earliest_expiry_source`), the whole days until it lapses
(negative once it already has), and a `suggested_action`:

* `renew` — still valid but inside your alert window; upload the
  replacement now.
* `renew_or_release` — already lapsed; renew immediately or decide to let
  the number go.

The look-ahead window defaults to 30 days. Tune it per organization with
the `numbers.document_expiry_alert_days` setting (1–365 days), or preview a
different window ad hoc with the `?days=` query parameter. Response rows
are sorted most-urgent first; a very large at-risk inventory is capped and
reports `truncated: true`, so narrow the window if you hit the cap.

***

## Tenant-owned by design

The split of responsibility is deliberate:

| Orbit (the platform)                                                                                           | You (the tenant)                                                               |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Encrypts and stores each document once, scoped to your organization.                                           | Supply the truthful, current documents in the first place.                     |
| Carries the profile and its documents to each carrier and reports the review status per provider.              | Choose which profiles a document backs, and in which role.                     |
| Flags documents approaching or past expiry per number.                                                         | Upload replacements and re-attach before a document lapses.                    |
| Enforces the gates — unregistered senders and unsatisfied profiles don't activate numbers or pass send checks. | Keep the profile's structured fields accurate as your business details change. |

Orbit never invents or auto-renews identity documents on your behalf — the
regulator is verifying *your* identity, so a renewal always starts with a
new upload from you. What the platform guarantees is that a document you
supply once is reusable everywhere it's accepted, and that you'll see its
expiry coming with enough lead time to act.

***

## Related references

* [Sender-ID Registration](/compliance/sender-id-registration) — per-country
  registration backed by `document_refs`.
* [Regulatory Preview](/numbers/regulatory-preview) — check which fields and
  documents a country requires before purchase.
* [Number Lifecycle](/numbers/lifecycle) — what happens to a number stuck at
  `pending_compliance`, and release/recovery.
* [Country Compliance Requirements](/compliance/country-requirements) — which
  sender types and documents each country accepts.
* [API Reference → Compliance](/api-reference/endpoints/compliance) — full
  request/response schemas.
