The Dualhook Platform API is a Bearer-authenticated REST API plus a co-branded onboarding URL that lets SaaS providers offer WhatsApp Business onboarding to their own end-customers. You bring tenants; Dualhook handles Meta's Embedded Signup, OAuth code exchange, Webhook Override subscription, sibling-WABA bookkeeping, and HMAC-signed lifecycle event delivery. End-users see your brand throughout, with a brief co-branded handoff to dualhook.com/onboard/<token> while Meta's Embedded Signup popup launches.
What the Platform API is
A small set of REST endpoints under https://dualhook.com/api/v1/ that you call from your backend to:
- create a one-time onboarding URL per tenant,
- read connection state and metadata,
- update or disconnect connections,
- reveal a connection's Cloud API access token on demand (audit-logged),
- and receive HMAC-signed lifecycle event webhooks when onboarding completes or a connection is removed.
Authentication is Authorization: Bearer dh_live_<random>. API keys are managed in the dashboard, with a 24-hour grace window on rotation so you can roll your servers without downtime.
Who this is for
If your SaaS lets multiple end-customers each connect their own WhatsApp number from inside your product, this is the API you want. Common shapes:
- Vertical SaaS (healthcare, real-estate, hospitality) onboarding many small-business clients, each with their own WABA — typically via Coexistence so the existing WhatsApp Business mobile app keeps working.
- B2B2C CRMs / shared inboxes that route messages to per-tenant backends and don't want a BSP in the message path (or the auto-mark-as-read behaviour that comes with proxy-based providers).
- Internal platforms at large orgs that need to provision business numbers programmatically as part of their tenant lifecycle.
If you only ever connect one or a handful of numbers for one business, the Developer, Team, or Agency tier is enough — you don't need Platform.
The flow at a glance
- Your backend creates an onboarding session.
POST /api/v1/onboarding/sessionswith your tenant id, the per-tenantwebhookOverrideUrlandwebhookVerifyToken, and your success/failure/cancel redirect URLs. - Dualhook returns a one-time onboarding URL. Valid for 1 hour.
- You render the URL inside your app, typically behind a "Connect WhatsApp" button.
- End-user clicks. They land briefly on
dualhook.com/onboard/<token>— co-branded with your logo and display name — and Meta's Embedded Signup popup launches. - Meta returns the OAuth code. Dualhook exchanges it, subscribes the Meta webhook to your URL, and creates the connection record.
- Redirect back to your app. End-user lands on your
successRedirectUrl?sessionId=…&status=completed. - Signed event webhook arrives. Your event endpoint receives
onboarding.completedwithwabaId,phoneNumberId,tenantId, and your round-tripped metadata, signed with HMAC-SHA256. - (Optional) Reveal the access token on demand.
POST /api/v1/connections/<id>/reveal-secretsreturns the Cloud API token withCache-Control: no-storeand writes an audit row.
Why the user lands on dualhook.com for a few seconds: Meta requires Embedded Signup to launch from a whitelisted domain on the Meta App, and only dualhook.com is on ours. The page is co-branded with your logo + display name, and the user is back in your app within seconds.
Reference
- Quickstart — 10 lines of Node.js to create your first session.
- Onboarding sessions — Create / get a session, idempotency, allowed redirect URLs, the WABA-scoped webhook constraint.
- Connections — List / get / update / disconnect, sibling-aware fan-out, health endpoints.
- Event webhooks — Lifecycle event types, payload shape, retry schedule.
- Webhook signatures — Verifying
X-Dualhook-Signature(HMAC-SHA256 over the raw body). - Rate limits — Per-scope budgets and
X-RateLimit-*headers. - Errors — Stable error codes and what each one means.
- Reveal access tokens — Audit-logged token reveal endpoint.