← All posts
Tutorial

What to Verify After WhatsApp Embedded Signup Completes

A completed WhatsApp Embedded Signup dialog is only the start of backend onboarding. Before marking a tenant ready, correlate the completion event with your server session, validate the returned token, identify the intended WhatsApp Business Account (WABA), confirm system-user access, register or verify the phone-number path, subscribe the app to the WABA, and prove one real webhook delivery. Treat each check as a separate acceptance gate.

Key takeaways

  • FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING proves that the Coexistence dialog reached its finish state; it does not prove that every backend step succeeded.
  • Meta’s official Embedded Signup collection requires integrations to fetch shared WABA IDs, manage system-user access, register the phone number when applicable, and subscribe the app for webhooks.
  • Never select the first WABA returned by a list call. Match the business and assets captured for the current onboarding session.
  • Credit-line attachment is required only for partner-paid billing models; it is not a universal readiness check.
  • A tenant is operational only after a signed, tenant-routed webhook reaches the expected receiver.

WhatsApp Embedded Signup post-onboarding verification checklist

Meta’s official Embedded Signup collection separates the browser flow from the required Graph API work. Its integration sequence includes fetching shared WABAs, adding or verifying system users, registering a phone number, subscribing the app to a WABA, and sharing a credit line when the provider owns billing.

That scope is different from the existing Embedded Signup v4 migration checklist, which focuses on moving the launch configuration and preserving Coexistence. This checklist begins after the finish event and defines the backend evidence needed before your application displays Connected.

GateEvidence to storeFailure boundary
Session correlationInternal tenant ID, state/nonce, configuration ID, completion timeA valid result can be attached to the wrong tenant
Token validationToken owner, app ID, granted scopes, expiry metadataA token exists but cannot manage the selected WABA
WABA selectionExact WABA ID mapped to the expected businessThe first shared WABA may belong to another customer
System-user accessAssigned system-user ID and required taskLater Graph API calls fail despite a completed dialog
Phone readinessPhone-number ID plus registration or Coexistence statusWABA access exists but messaging is not ready
App subscriptionWABA appears in subscribed_appsMessages arrive at Meta but not at your webhook
Delivery proofOne real event, tenant routing result, acknowledgementConfiguration looks correct without end-to-end evidence

Implement the gates in order

1. Correlate the browser result with a server-side session

Create the onboarding session on your server before opening the Meta dialog. Store a one-time state value with the tenant, user, configuration ID, and intended onboarding path. Accept the finish payload only once, reject expired or mismatched state, and avoid placing access tokens in browser logs or analytics.

For Coexistence, record the documented FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING event. For another Embedded Signup path, use that path’s current official completion contract. Do not route all variants solely by a display string or one numeric version.

2. Validate the token before using asset IDs

Use Meta’s token-debugging flow to confirm that the token belongs to your app and carries the permissions needed by your integration. A non-empty token is not proof of authorization. Persist only the minimum server-side metadata needed for audit and renewal; do not write the token itself into application logs.

3. Resolve the intended WABA deterministically

Fetch the shared or client WABAs available to the business, then match the expected WABA ID and business context from the current session. Multi-tenant systems must not assume array order. If no exact match exists, leave the tenant in a recoverable verification_required state instead of silently attaching another asset.

4. Verify the system user and phone-number path

The official collection exposes GET /{waba-id}/assigned_users to verify that the expected system user has access. Check the task your backend needs rather than treating any assignment as sufficient.

Then branch by onboarding type. A standard Cloud API flow may require phone-number registration. A Coexistence flow uses a number already connected through the WhatsApp Business app, so validate the current Coexistence state instead of registering it again. The Coexistence decision guide explains when that official two-surface model is actually needed.

5. Subscribe the app and prove delivery

Call POST /{waba-id}/subscribed_apps with the required server-side credentials, then verify the subscription. Keep subscription state separate from phone registration: either one can succeed while the other fails.

Finally, send or receive a controlled test message and require one real webhook to pass tenant lookup, payload validation, deduplication, and acknowledgement. For UnifyPort receivers, the equivalent acceptance path is documented in webhook delivery and signature verification: verify X-Device-Timestamp and X-Device-Signature against the raw body when the endpoint has a signing_secret.

async function verifyWabaAccess({ graphVersion, businessId, wabaId, token }) {
  const base = `https://graph.facebook.com/${graphVersion}`;
  const headers = { Authorization: `Bearer ${token}` };

  const [shared, assigned, subscribed] = await Promise.all([
    fetch(`${base}/${businessId}/client_whatsapp_business_accounts`, { headers }),
    fetch(`${base}/${wabaId}/assigned_users?business=${businessId}`, { headers }),
    fetch(`${base}/${wabaId}/subscribed_apps`, { headers }),
  ]);

  if (![shared, assigned, subscribed].every((response) => response.ok)) {
    throw new Error('embedded_signup_verification_failed');
  }

  return Promise.all([shared.json(), assigned.json(), subscribed.json()]);
}

Pin graphVersion to a Meta Graph API version your app currently supports; do not silently inherit a changing default.

Where UnifyPort fits

UnifyPort does not complete Meta Embedded Signup, assign WABA permissions, register Cloud API phone numbers, attach a credit line, or preserve Coexistence. The official flow is the right choice for a Solution Partner or Tech Provider that needs those assets.

UnifyPort fits a narrower path: connect an ordinary WhatsApp account and receive supported inbound messages as normalized message.received events. If the requirement is an inbound queue rather than customer WABA provisioning, compare the three WhatsApp inbound paths and then follow the WhatsApp authorization guide.

Limitations and trade-offs

This checklist cannot prove Meta business eligibility, app-review approval, display-name approval, number quality, or policy compliance. Those are separate platform states. It also cannot turn a successful test tenant into proof that every customer configuration will work.

An unofficial interface cannot grant official Cloud API assets or replace Embedded Signup for a multi-tenant SaaS that manages customer WABAs. Conversely, a finished Embedded Signup flow does not prove that your tenant mapping, retry handling, webhook receiver, or billing boundary is correct. Keep the browser result and operational acceptance as separate states.

FAQ

What does FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING mean?

It means the WhatsApp Business app onboarding dialog reached its documented finish state. Your backend must still validate the session, assets, authorization, subscription, and delivery.

Is the Embedded Signup access token enough to mark a customer connected?

No. Validate the token and match the exact WABA, system user, phone-number path, and webhook subscription before changing the tenant to ready.

Must every integration attach a credit line?

No. Credit-line sharing applies when the provider pays Meta and bills the customer. Customer-paid or other supported billing arrangements need their own documented check.

Should a Coexistence number be registered again after signup?

No. Coexistence uses a number already connected through the WhatsApp Business app. Validate its documented state and synchronization path instead of repeating standard phone registration.

What is the final acceptance signal?

One controlled webhook delivered to the correct tenant, validated and acknowledged by your production-equivalent receiver, is the minimum operational proof.

Next step

Implement the gates against Meta’s official Embedded Signup collection before enabling a tenant. If you only need ordinary-account inbound messaging, evaluate the separate UnifyPort WhatsApp authorization path.

Sources

Official sources checked on 2026-08-05: