---
title: "Connect WhatsApp from Embedded Signup"
method: POST
path: "/v1/connect/whatsapp/embedded-signup"
tags: ["Connect"]
---

# Connect WhatsApp from Embedded Signup

`POST /v1/connect/whatsapp/embedded-signup`

Exchange the authorization code Meta's Embedded Signup popup returned. This is the call the Zernio-hosted
signup page makes after the popup closes (`GET /v1/connect/whatsapp?signup=hosted`), sending the `wabaId`
and `phoneNumberId` Meta reported so exactly the chosen number is connected; when both are omitted the
first number the token can see is used. The code never passes through a `redirect_uri`, so
`POST /v1/connect/{platform}` cannot accept it. Authenticates with an API key, or with the connect token
the hosted flow issues (`X-Connect-Token` header).

## Headers

- `X-Connect-Token` string

## Request body

- object
  - `code` string, required — Authorization code from the WA_EMBEDDED_SIGNUP postMessage
  - `profileId` string, required
  - `wabaId` string — WhatsApp Business Account id, when the SDK reported one
  - `phoneNumberId` string
  - `isCoexistence` boolean — Number is also live in the WhatsApp Business app
  - `expectedPhoneNumber` string — Rejects the connect when Meta returns a different number
  - `redirectUrl` string — Hosted signup page only. When present, the response also carries `redirectUrl`, the URL the user should land on, with the outcome mapped exactly like the redirect flow (success params, or `error` and `platform` with the same values). Must be an absolute http(s) URL or a custom app scheme.
  - `echoConnectToken` boolean — Hosted signup page only. Append the connect token to the success redirect, as the redirect flow does for API-key callers.

## Response `200`

Number connected

- object
  - `message` string
  - `account` object
    - `accountId` string
    - `platform` 'whatsapp'
    - `username` string
    - `displayName` string
    - `isActive` boolean
    - `selectedPhoneNumber` string
  - `redirectUrl` string — Present only when `redirectUrl` was sent; also present on error responses.

## Other responses

- `400` — Invalid request
- `401` — Unauthorized
- `402` — Payment method or enterprise contract required. The authenticated account hit a billing gate before the connection could proceed. Three reasons: - `free_tier_exceeded`: the team has connected more accounts than the free tier allows. Add a payment method on the dashboard to continue (the user will be billed per additional connected account). - `twitter_passthrough`: connecting an X account requires a card on file from day one because X API calls incur real per-call pass-through costs. Applies to the 1st X account, not only the 3rd+. - `enterprise_required`: the team is on an enterprise contract with a negotiated connected-account cap and has reached it. Self-service teams have NO connected-account cap (the $1/account rate continues at any scale), so this reason can only fire for teams whose contract sets an explicit limit. `dashboard_url` deep-links to the enterprise contact page rather than the billing tab. The end-user already has a card on file; this gate is about contract terms, not card collection. SDK consumers should switch on `reason` to render the right prompt. For `free_tier_exceeded` and `twitter_passthrough`, redirect the end-user to `dashboard_url`: it opens the add-payment-method drawer on the Zernio billing page, and the request succeeds once the card is on file. For `enterprise_required`, redirect to `dashboard_url` (the enterprise contact form) to adjust the contract's limit.
- `409` — The number is already connected on another profile or team

## Changes

- **2026-09-16** `3e6ddf2a99ea` — 1 info
  - added the optional property `details/budgetScope` to the response with the `400` status
- **2026-09-15** `0dba7d004d75` — 2 info
  - added the optional property `details/quotaExhausted` to the response with the `400` status
  - added the optional property `details/quotaScope` to the response with the `400` status
- **2026-09-09** `41eff0cffb2d` — 4 info
  - added the new optional `header` request parameter `X-Connect-Token`
  - added the new optional request property `echoConnectToken`
  - added the new optional request property `redirectUrl`
  - added the media type `application/json` for the response with the status `200`
- **2026-08-25** `44b6b1ca2a8b` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/connect/whatsapp/embedded-signup/post.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/eded32b62823?raw)
