Guide

How to add WhatsApp Embedded Signup to a SaaS product

WhatsApp Embedded Signup is Meta's official way to let your SaaS customers connect their own WhatsApp Business number from inside your product. Implementing it from scratch means owning a Meta Business App, completing App Review, running Embedded Signup's JS launcher, exchanging an OAuth code, subscribing webhooks, and maintaining the integration as Meta's Cloud API evolves. Most SaaS teams don't actually want any of that — they want a Connect WhatsApp button that just works. Here's how Embedded Signup actually works, what your team would own if you build it, and what Dualhook handles instead.

What is WhatsApp Embedded Signup?

Embedded Signup is Meta's hosted onboarding flow for connecting a WhatsApp Business Account (WABA) to a Cloud API integration. It launches as a popup from a whitelisted domain, walks the end-user through Facebook login, Business Portfolio selection, WABA + phone-number selection, and OAuth permission grants. When the user finishes, Meta returns a short-lived OAuth code to the launching app, which the app then exchanges for a long-lived system-user access token.

It exists for one reason: Meta wants Tech Providers, Tech Partners, and Solution Partners to be able to onboard business customers to Cloud API without each business having to navigate Meta Business Suite manually. From the end-user's perspective it's a 90-second flow.

Why SaaS platforms need it

If your product lets your own customers connect their own WhatsApp number — vertical SaaS for clinics, real estate, hospitality; B2B2C CRMs; shared inboxes; e-commerce enablement — the alternative to Embedded Signup is asking each customer to do Cloud API setup themselves in Meta Business Suite. That's a hard ask. It's the leading cause of stuck onboardings.

Embedded Signup turns a multi-day Meta config dance into a single Connect WhatsApp button inside your product.

What Meta requires

  • A Meta Business App (yours, or your provider's) with the whatsapp_business_management and whatsapp_business_messaging permissions.
  • App Review approval for those permissions on the live app — sandbox apps cannot run Embedded Signup against real businesses.
  • A whitelisted launching domain configured on the Meta App.
  • Tech Provider, Tech Partner, or Solution Partner role on the WABAs you onboard.
  • Webhook subscription handling — every subscribed WABA needs a callback URL and verify token registered via POST /{wabaId}/subscribed_apps.
  • An OAuth code exchange endpoint on your backend that swaps the short-lived code for a permanent access token.

What Dualhook abstracts away

Dualhook is the Tech Partner handling the WhatsApp Cloud API onboarding layer on the connection. That means the Meta App, the App Review, the Embedded Signup launcher, the OAuth code exchange, the access-token storage, and the Webhook Override subscription all run on Dualhook's side. Your team never touches Meta Developer Console.

What you ship instead is a backend endpoint that creates a Dualhook onboarding session per tenant, plus a webhook endpoint that receives the signed onboarding.completed event when the user is done.

How the Dualhook Platform flow works

  1. 1

    Create an onboarding session

    POST /api/v1/onboarding/sessions with your tenantId, tenantName, success/failure/cancel redirect URLs, and the per-tenant webhookOverrideUrl + webhookVerifyToken.

  2. 2

    Render the returned onboarding URL

    Behind a Connect WhatsApp button. The URL is one-time and expires after 1 hour.

  3. 3

    End-user clicks

    They land on dualhook.com/onboard/<token> for a few seconds, see your logo and display name, and Meta's Embedded Signup popup launches.

  4. 4

    Meta returns the OAuth code

    Dualhook exchanges it, subscribes the Meta webhook to your tenant's URL, and creates the connection.

  5. 5

    End-user is redirected back

    to your successRedirectUrl?sessionId=…&status=completed.

  6. 6

    Your event endpoint receives the signed event

    onboarding.completed with wabaId, phoneNumberId, tenantId, connectionMode when Meta returned it, and your round-tripped metadata, signed with HMAC-SHA256. If the mode is initially unknown, subscribe to connection.mode_resolved instead of polling.

  7. 7

    Reveal the access token on demand

    POST /api/v1/connections/<id>/reveal-secrets when you need it. The reveal is audit-logged against your API key.

Common mistakes when building it yourself

  • Skipping App Review and getting stuck on a sandbox app that can't onboard real businesses.
  • Treating Embedded Signup as a one-time integration — Meta ships breaking-ish changes (BSUIDs, Coexistence, Meta Verified) on a continuous schedule.
  • Forgetting that if you implement Embedded Signup against Meta's WABA-level subscribed_apps endpoint (the simpler path most teams take first), all phone numbers under that WABA share one webhook URL and verify token. Onboarding the second number with a different verify token silently breaks the first. Meta does support per-phone-number overrides — but you have to opt into the more complex path explicitly.
  • Storing access tokens in your application database with no audit trail of who fetched them and when.
  • Not implementing retry on the lifecycle events you fire downstream — Embedded Signup completion is the trigger for a lot of provisioning logic, and a single dropped delivery breaks tenants.
  • Reading messages on Dualhook's behalf — Webhook Override exists exactly so you don't have to put a proxy in the message path.

Build vs buy: the short version

If you're a SaaS company shipping WhatsApp as one feature among many, building Embedded Signup yourself is rarely worth it. The deeper comparison is in the Build vs buy guide — pricing, ongoing maintenance burden, and the per-area responsibility split are all there.

Ready to skip the Meta setup?

Spin up an API key on the Platform tier and create your first onboarding session in minutes.