For the complete documentation index, see llms.txt. This page is also available as Markdown.

Passkey Authorization for White Label Partners

WhatsApp has introduced an additional Passkey step for some device-linking attempts. For affected accounts, scanning the QR code may no longer be enough to complete authorization.

To support this flow in white label integrations, Whapi.Cloud provides the QR Connection Snippet — a standalone JavaScript widget that partners can embed directly into their own dashboard or customer portal.

The snippet is a complete replacement for your existing QR authorization block. It already handles:

  • QR polling;

  • QR code display;

  • countdown and expiration;

  • automatic QR refresh;

  • Passkey detection;

  • Manual Paste authorization;

  • waiting, reset, and error states.

Replace your current QR block with the snippet embed code. Do not run your own QR polling, countdown, or refresh logic in parallel.

Your application only needs to:

  • select the channel;

  • provide its api-url and token;

  • react when the channel becomes authorized.

The widget does not use an iframe. It is implemented as the <whapi-qr-connection> Web Component and rendered inside Shadow DOM, so the host page’s styles do not affect its layout.

Get snippet here:

Pairing Code support

How to add the widget

Choose the bundle that matches your page language: en / es / tr / ru / pt

Place the element where the authorization widget should appear and load the language bundle once on the page:

Replace:

  • CHANNEL_API_URL with the channel API URL, for example https://gate.whapi.cloud;

  • CHANNEL_TOKEN with the token of the channel being authorized.

Both values must belong to the same Whapi.Cloud channel.

How the authorization flow works

  1. The widget requests the current QR data from: /users/login/rowdata

  2. The user scans the QR code.

  3. For accounts without the new Passkey requirement, the normal connection flow continues.

  4. If WhatsApp requests Passkey confirmation, the QR code is replaced with the Passkey authorization screen.

  5. At the moment, Manual Paste is the available method. AutoPasskey and Chrome Passkey are shown as in development.

  6. The user follows the instructions in the widget, runs the provided script in the browser console on web.whatsapp.com, and pastes the returned JSON into the widget.

  7. After the response is accepted, the widget shows the waiting screen while the user completes the remaining confirmation on the phone.

The partner does not need to implement the Passkey API flow separately!


Dynamic initialization

The widget can also be mounted through JavaScript:

Optional events

The widget emits browser events that can be used in the partner interface:

Event
When it fires
event.detail
Recommended partner action

rowdata

Each successful GET /users/login/rowdata

Full API response: status, type, rowdata, expire, …

Optional: analytics/debug. Do not treat as connected. Widget renders QR/Passkey internally.

qr

Passkey challenge shown (type: "webauthn")

Passkey challenge object

Optional: show your own Passkey help link (widget has no extended tooltip).

paste

Manual Paste submitted successfully

Parsed JSON sent to API

Optional: logging. Usually no navigation yet.

waiting

After successful paste; widget on waiting screen

undefined

Show «complete on phone» state; optionally poll channel health or wait for webhook. Not final success.

authorized

Channel connected (HTTP 409 on rowdata poll)

{ contact, health, healthError?, reason }

Primary success handler: redirect to channel dashboard, hide auth widget, refresh channel list.

reset

User clicked Reset; logout succeeded

undefined

Clear any partner-side «connecting» UI state.

error

Rowdata or logout API failure (string message)

Error string

Show retry / support message.

Events qr, paste, and waiting appear only when WhatsApp requires Passkey. In a normal QR-only flow you will see rowdata polling followed by authorized.

Example:


Fires once when authorization completes. The widget has already switched to the connected state.

event.detail:

  • contact — WhatsApp profile (id, name, profile_pic, …)

  • health — channel health from GET /health (status, channel_id, uptime, …)

  • healthError — present only if /health failed (authorization still succeeded)

  • reason:

    • rowdata-conflict — completed via QR scan (normal flow)

    • passkey-conflict — completed via Passkey / Manual Paste flow

Recommended action:

  • Redirect the customer to your authorized channel page, or

  • Replace the widget area with your own «connected» UI using detail.contact / detail.health.

You may still use webhooks or server-side health checks as a backup, but authorized is the widget's built-in completion signal.

Full White Label Mode


Important integration notes

  • Do not place the channel token directly into publicly accessible static HTML. Provide it only after the customer is authenticated in your system.

  • Do not treat the QR scan as the final connection event. Some users may need to complete Manual Paste before authorization succeeds.

  • Continue using your existing channel status polling or webhooks to detect the final authorized state.

  • Add your own explanation or documentation link for Passkey and Manual Paste, as the embedded widget does not include the extended tooltip or Help Center link available in the Whapi.Cloud dashboard. Read more here: New Passkey Step When Connecting WhatsApp

Last updated