Skip to main content

Assemble a Shared Compliance Profile Across Gated Surfaces

A compliance profile (cprof_…) is a reusable KYC packet: the identity and business data carriers and regulators review, approved once, then referenced by every surface that asks for it. The packet itself is documented field-by-field on KYC Documents & the Compliance-Profile Lifecycle, and the four attach/mutate/delete error codes have their own runbook on Compliance profile lifecycle errors. This guide is the end-to-end pattern: why one profile is shared, how it backs several surfaces at once, how to rotate it without downtime, and how to see expiry coming before it gates a launch.
Compliance posture is tenant-owned. You choose which profiles back which surfaces; Orbit enforces the lifecycle gates, and the approval itself always comes from the carrier or regulator reviewing your packet. Orbit never mandates that a given surface use a given profile.

One shared packet, not five per-surface packets

The alternative to a shared profile is the per-surface packet: one KYC bundle for your German numbers, another for your alphanumeric Sender ID, another for your US 10DLC brand. That buys you five review queues, five renewal calendars, and five chances for a document to lapse on one surface while the other four still work. A shared profile inverts that: the carrier reviews the packet once, and every surface referencing its id inherits the approval. A profile that matches both a use case and a country is fair to reuse — your phone_number_purchase DE profile can back every German number you buy, and one document library backs profiles for every surface. Reuse is a choice you make at attach time; nothing attaches a profile without your id. The trade to weigh: a shared profile funnels its surfaces through one review and one expiry clock, so keep profile scope tight enough that a rejection doesn’t idle assets you could have split. Most tenants run a handful of deliberately-scoped shared profiles rather than one global one.

Lifecycle states and the two guards

A profile moves through one fixed review lifecycle, with three side-exits:
Only draft, rejected, and partially_rejected are editable; everything else is frozen by design. Two guards protect the frozen states: LOCKED (409 COMPLIANCE_PROFILE_LOCKED) on any mutation past draft, and IN_USE (409 COMPLIANCE_PROFILE_IN_USE) on delete or document-detach while a downstream asset still references the profile. The state-by-state map and the unblocked path for each code are on Compliance profile lifecycle errors — read it before you treat a 409 as a bug.

One approved profile, many surfaces

Each gated surface reads the same packet. Map the use case to the surface it opens: Pass the profile id explicitly at attach time — an explicit compliance_profile_id is always safer than relying on a surface’s auto-pick. For a number purchase:
The surface resolves the id, reads the profile’s status, and opens only on approved; any other status answers the same 422 as a missing profile. Sender IDs, brands, and campaigns attach from their console surfaces or their own attach endpoints; numbers also accept POST /api/v1/numbers/:id/attach-compliance-profile after the fact.

Upload documents once, reference by doc_…

Documents live in a tenant-wide library, not inside any profile. Upload the file once, then attach its doc_… id to as many profiles as accept it — with a role (id_proof, address_proof, business_doc, authorization, other) that may differ per profile. The same business registration can back a German phone-number profile today and a Sender-ID filing tomorrow. The upload call, accepted types, and the renewal-by-re-upload pattern are on KYC Documents & the Compliance-Profile Lifecycle.

Rotate without downtime

The old profile keeps serving traffic while its replacement clears review — a swap is never a gap. Work this order:
  1. Clone the frozen profile — clone copies fields, metadata, and document attachments into a new editable draft:
  2. Fix and submit the clone — edit the still-editable draft against the reviewer’s notes (or the country’s checklist), submit, and wait for approved. Use the same sequence for an expired profile you need to re-verify.
  3. Re-attach downstream — point each number, sender, brand, and campaign at the new id (POST /api/v1/numbers/:id/attach-compliance-profile for numbers; the console attach surface for everything else).
  4. Detach and delete the old profile — only once nothing references it. A delete attempt while an asset still points at it answers 409 COMPLIANCE_PROFILE_IN_USE; the detach walk clears it.

See expiry before it gates a launch

Orbit derives per-number expiry alerts from the timestamps it already stores — each attached document’s expires_at, and the carrier verify-by deadline on numbers waiting at pending_compliance:
Each alert names the number, the soonest binding expiry, the source (document or carrier deadline), the days until it lapses, and a suggested_action:
  • renew — still valid but inside your alert window; upload the replacement document 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 with the numbers.document_expiry_alert_days setting or the ?days= query parameter. Field details are on KYC Documents & the Compliance-Profile Lifecycle.

First-launch checklist

Work this order the first time you wire a gated surface:
  1. Read the destination’s country rules — the per-market packet a profile is graded against, on Country Compliance Requirements.
  2. Preview the requirements — run regulatory preview so the exact fields and documents are settled before you create the profile.
  3. Upload documents to the library; get back doc_… ids.
  4. Create the profile (POST /api/v1/compliance/compliance-profiles or Settings → Compliance → Profiles), attach documents by id with their roles, and fill the structured fields.
  5. Submit and wait for approved.
  6. Attach by id at the surface — explicit compliance_profile_id on the purchase or registration.
  7. Set the expiry windownumbers.document_expiry_alert_days, sized to your renewal lead time.
  8. Know the rotation path — clone, fix, re-attach, detach-old — before a reviewer note or an expiry alert forces it.