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

# WhatsApp Business verification as a compliance profile

> The whatsapp_business_verification compliance-profile use case — the WABA-onboarding packet Meta requires before a number can send — its packet shape, lifecycle states, rejection handling, renewal, and how it gates WhatsApp traffic.

# WhatsApp Business verification as a compliance profile

Before a WhatsApp Business Account (WABA) can send at volume, Meta requires
one packet: **business verification** — proof that the legal entity behind
the WABA is real, reachable, and matches the display name it shows
recipients. In Orbit that packet lives on the shared compliance-profile
model as `use_case = "whatsapp_business_verification"`: it follows the same
lifecycle, reuses the same document library, and answers the same status
endpoints as every other packet. This page is the WhatsApp-specific
walkthrough of that model. The onboarding mechanics — embedded signup,
number OTP, display-name submission — live on
[WABA setup](/guides/whatsapp/waba-setup); **template content policy** is a
different review and lives on
[WhatsApp content policy](/compliance/whatsapp-content-policy).

<Note>
  Compliance posture is tenant-owned. You assemble the WABA verification
  packet; Orbit carries it to Meta, enforces the lifecycle gates, and runs
  the send-time check — the approval itself always comes from Meta, not
  from Orbit. Orbit never verifies a business on your behalf and never
  mandates which Business Manager backs a WABA.
</Note>

***

## 1. What the profile controls — the packet, not the WABA

`whatsapp_business_verification` composes the compliance record Meta
grades. Distinct from the WABA itself:

* **The packet Meta reviews** — business legal name, registered address,
  website (with a live privacy policy), display-name rationale, the Meta
  Business Manager ID that owns the WABA, and the supporting KYC documents
  Meta's reviewer cross-checks: business licence or certificate of
  incorporation, a utility bill or bank statement as address proof, and —
  for the Business Manager admin — a government ID uploaded inside Meta's
  own flow.
* **The WABA is onboarding mechanics.** Creating the WABA, connecting it
  through embedded signup, adding and OTP-verifying the phone number, and
  setting the display name are walked on
  [WABA setup](/guides/whatsapp/waba-setup). This page is the compliance
  record those steps feed into — the profile tracks the verification state
  of the *business behind* the WABA, not the connection state of the WABA
  itself.
* **Template content is a third review.** Meta grades message templates
  against its Commerce and Business Messaging policies
  ([WhatsApp content policy](/compliance/whatsapp-content-policy)). A
  verified business does not pre-approve any template, and an approved
  template does not verify the business — the two reviews are independent.

In the profile, `country_code` is optional (WhatsApp verification is
country-agnostic) and the use case requires no carrier-file documents of
its own — the registry defines no `documentRoles` and no `dataFields` for
it, because the documentary evidence Meta wants is uploaded **inside Meta
Business Manager's Security Center**, not through Orbit's packet. What
Orbit tracks is the *status* of that verification: submission resolves the
tenant's connected WABA, reads the owning Meta Business's
`business_verification_status` from the Graph API, and keeps the profile in
step with that read on every status-sync. The documents Meta actually
checks live in Meta's review — but the same `doc_…` library files you keep
for [KYC documents](/compliance/documents-kyc) are the ones you upload
there, so the library stays the single source for re-submission.

***

## 2. Lifecycle walkthrough — attach, then poll Meta's read

The profile follows the shared lifecycle map on
[Assemble a Shared Compliance Profile](/compliance/compliance-profile-assembly):
`draft → pending_review → approved`, with `rejected` /
`partially_rejected` and `expired` as the terminal variants, and the same
LOCKED/IN\_USE error codes once a profile is past `draft`. The Meta-specific
walkthrough:

1. **Connect a WABA first.** Submission is a *status-read attach*: the
   provider resolves the tenant's connected WABA from the organization
   settings the embedded-signup flow stored, so
   [connect the WABA](/guides/whatsapp/waba-setup) before creating the
   profile.

2. **Create the profile** as a `draft` with
   `use_case = "whatsapp_business_verification"`:

   ```bash theme={null}
   curl -X POST https://api.orbit.devotel.io/api/v1/compliance/compliance-profiles \
     -H "Authorization: Bearer $ORBIT_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{
       "use_case": "whatsapp_business_verification",
       "name": "Acme WABA — Meta business verification"
     }'
   ```

3. **Submit the profile**
   (`POST /api/v1/compliance/compliance-profiles/:id/submit`). Submit
   resolves the connected WABA, reads the owning Meta Business id, and
   persists it as the provider bundle id. The profile moves to
   `pending_review` and now mirrors Meta's live verification state.

4. **Poll status on Meta's read.**
   `GET /api/v1/compliance/compliance-profiles?use_case=whatsapp_business_verification`
   returns the profile's current status; the background resync tick
   re-reads the Graph `business_verification_status` edge and moves the
   profile when Meta moves. `verified` / `approved` at Meta maps to
   `approved` here; `rejected` / `failed` / `declined` / `revoked` maps to
   `rejected`; `expired` maps to `expired`; anything still in flight
   (`pending`, `in_review`, `not_verified`) maps to the in-flight states.
   Use `POST /api/v1/compliance/compliance-profiles/:id/resync` to force a
   re-read instead of waiting for the next tick.

Because Meta's verification is performed **inside Business Manager** (the
Security Center document upload — there is no Graph REST "submit" endpoint
for it), the profile never manufactures the packet: it tracks the state of
the verification you ran on Meta's side. The window where you can connect
and send at the unverified cap (250 unique recipients per day) is covered
on [WABA setup](/guides/whatsapp/waba-setup) — that cap is Meta's, and the
profile flipping to `approved` is what lifts it.

***

## 3. Rejection handling — the reasons Meta gives

A rejected profile stays editable and carries the mapped reason. The Meta
rejections that recur:

* **Display-name mismatch** — the name you submitted for review does not
  match the legal or trade name on the documents Meta holds (a DBA that is
  not on your incorporation record is the canonical form). Meta also denies
  generic names ("Support") and names with disallowed characters.
* **Business verification incomplete** — the Security Center upload was
  cropped, edited, out of date, or the entity details typed in Business
  Info do not match the document (name spelling, address, tax id). Meta's
  review is OCR + manual, and it denies partial documentation rather than
  asking for more.
* **Unverified domain / placeholder website** — the website you listed has
  no real content, the privacy policy is missing or hosted on a free
  placeholder page, or the business email is on a consumer domain. Meta
  reads the site during review.

The fix for all three runs on Meta's side — correct the record or the
upload inside Business Manager, then re-enter review — and the profile
follows: resync moves it back to `pending_review` while Meta re-reads, and
to `approved` when Meta clears it. Keep
[WABA setup's failure matrix](/guides/whatsapp/waba-setup#failure-matrix---the-four-most-common-stuck-states)
handy for the four stuck states (pending-review backlog, display-name
rejection, OTP issues, billing) — the compliance profile is the observable
of the first two.

***

## 4. Renewal and re-review — documents carry across re-submissions

Two events move an approved profile backward:

* **The business information changes.** A legal-name change, a new
  registered address, a re-domiciled entity — Meta wants the Security
  Center upload refreshed when the underlying record changes, and its read
  of the Business's verification state moves away from `verified` until the
  re-review clears. The profile follows that read on the next resync.
* **The verification expires.** Meta can mark a long-stale verification
  `expired`; the profile maps that to `expired` and the send-time gates
  that ask for an `approved` packet treat it as no longer satisfied.

In both cases the documents do not start over. The tenant-wide
[KYC document library](/compliance/documents-kyc) keeps the business
licence, utility bill, and address proof by `doc_…` id, so a re-submission
— on Meta's side or on any other profile the same business backs — reuses
the ids it already has. That reuse is the reason the lifecycle doc says
upload once, reference everywhere: a re-entered review is a re-attach, not
a re-collect.

***

## 5. Business verification status, quality rating, and messaging tier

Meta grades a WABA on three axes that tenants routinely conflate — keep
them separate:

* **Business verification** — does the legal entity behind the WABA check
  out. This page's profile. Gates the move past the unverified 250/day cap.
* **Quality rating** — how recipients react to the traffic the WABA sends
  (blocks, reports, read rates). Read it on
  [WhatsApp quality and health](/concepts/whatsapp-quality-and-health); it
  moves tier progression and can freeze a tier when it degrades.
* **Messaging tier** — the 250 → 1,000 → 10,000 → 100,000 → unlimited
  ladder. Business verification is a precondition to climb it; quality
  rating is the signal that actually moves the tier.

An approved verification with a Low quality rating still stalls — Meta
requires both, and the profile's `approved` state only answers the first.

***

## 6. Where the gate fires at send time

The WhatsApp business-verification check runs on the same
[send gates](/compliance/send-gates) plane as every other pre-dispatch
gate. Which surfaces refuse on a non-approved WABA:

* **Template-message sends** on a WABA whose business-verification profile
  is not `approved` are held before dispatch — the gate the send-time check
  answers against. Session (24h-window) replies are not gated on the
  profile, but Meta's own tier cap still bounds them.
* **Number activation and tier progression** — Meta's side: the unverified
  cap and the tier ladder on
  [WABA setup](/guides/whatsapp/waba-setup#step-7----go-live-gates) are
  Meta's own enforcement; Orbit's gate mirrors it so a non-approved WABA
  fails fast instead of failing at Meta.

Match a held send to this gate against the
[send-gate decision fork](/compliance/send-gate-decision-fork) — it maps
the error code to the gate that fired and the dashboard surface to open
first.

Registration stays tenant-owned for the same reason every other packet
does: Orbit carries what you submit and enforces the lifecycle transitions,
but Meta's approval — and the documents you upload to Meta — are yours, not
Orbit's.

***

## Related references

* [WABA setup](/guides/whatsapp/waba-setup) — the end-to-end onboarding
  path: Business Manager verification, number procurement, embedded signup,
  OTP, display name, go-live gates.
* [WhatsApp content policy](/compliance/whatsapp-content-policy) — the
  independent template-content review Meta runs.
* [WhatsApp quality and health](/concepts/whatsapp-quality-and-health) —
  quality rating, messaging tier, and the recovery loop — the two Meta
  signals this profile does *not* carry.
* [KYC Documents & the Compliance-Profile Lifecycle](/compliance/documents-kyc) —
  the tenant-wide document library re-submissions reuse.
* [Assemble a Shared Compliance Profile](/compliance/compliance-profile-assembly) —
  the shared lifecycle map, attach-by-id, and rotation path.
* [Compliance profile use cases](/compliance/compliance-profile-use-cases) —
  the full use-case catalogue this profile registers on.
* [Send gates](/compliance/send-gates) and the
  [send-gate decision fork](/compliance/send-gate-decision-fork) — where
  the gate fires and how to read a held send back to this gate.
* [API Reference → Compliance](/api-reference/endpoints/compliance) — the
  profile endpoint surface.
