Platform API: Quickstart

10-line code sample to create your first onboarding session and redirect a tenant to the co-branded Embedded Signup flow.

The Dualhook Platform API lets your backend create a one-time co-branded WhatsApp onboarding URL for any tenant in 10 lines of code. Your tenant clicks Connect WhatsApp, completes Meta's Embedded Signup, and your event endpoint receives a signed onboarding.completed payload with the new connectionId.

Run in Postman / OpenAPI

Open the public Postman workspace: Dualhook Platform API on Postman. Fork the workspace into your own, set the DUALHOOK_API_KEY collection variable to your dh_live_… key, and run any request. The Create onboarding session request captures the returned sessionId into a collection variable so the next call (Get onboarding session) just works.

Prefer to import locally? Grab the JSON: dualhook-platform-api.postman_collection.json. The OpenAPI 3.1 source for the collection lives at openapi/platform-api.yaml.

What this does

POST /api/v1/onboarding/sessions returns a one-hour-valid onboardingUrl you can render inside your app. When the tenant finishes Meta's Embedded Signup, Dualhook exchanges the OAuth code, subscribes the Meta webhook to the URL you supplied, and fires an HMAC-SHA256 signed onboarding.completed event to your event endpoint.

Create your first session

const r = await fetch("https://dualhook.com/api/v1/onboarding/sessions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.DUALHOOK_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    tenantId: customer.id,
    tenantName: customer.name,
    successRedirectUrl: `https://app.example.com/done?cust=${customer.id}`,
    failureRedirectUrl: `https://app.example.com/error?cust=${customer.id}`,
    cancelRedirectUrl: `https://app.example.com/cancel?cust=${customer.id}`,
    webhookOverrideUrl: "https://api.example.com/whatsapp",
    webhookVerifyToken: process.env.MY_WEBHOOK_VERIFY_TOKEN,
  }),
});
const { onboardingUrl } = await r.json();
return redirect(onboardingUrl);

The response also includes sessionId and expiresAt. Sessions are valid for 1 hour by default (pass expiresInSeconds, 300–86400, to override). Idempotency-Key is optional but recommended — reusing the same key with the same body returns the same session. Note that Dualhook preflights the webhookOverrideUrl with a simulated Meta verification GET at creation time — see onboarding sessions for the endpoint requirements and the skipWebhookPreflight escape hatch.

After the user completes onboarding

successRedirectUrl will receive ?sessionId=…&status=completed. Your event endpoint (configured in the dashboard) will receive a signed onboarding.completed payload with connectionId, wabaId, phoneNumberId, tenantId, and your round-tripped metadata.

To fetch the Cloud API access token for that connection:

POST /api/v1/connections/<connectionId>/reveal-secrets
{ "secretTypes": ["access_token"] }

The response carries Cache-Control: no-store. Every reveal is recorded in the audit log against the API key that called it.

Next steps

Related

  • Platform API (Multi-Tenant Onboarding)Build embedded WhatsApp onboarding into your SaaS. Programmatic connection creation, per-tenant webhook routing, HMAC-signed event webhooks.
  • Platform API: Onboarding sessionsCreate and look up co-branded onboarding sessions. Idempotency, redirect URL whitelisting, expiry, and the 1-hour session window.
  • Platform API: Event webhooksReceive HMAC-SHA256 signed lifecycle events: onboarding, connection.mode_resolved, disconnect, and coexistence heartbeat events.
Browse more docsStart Free Trial