Skip to main content

Remote pairing — hosted pairing link

For SaaS platforms that manage numbers for end customers, Remote Pairing lets you generate a pairing link instead of displaying the QR code yourself. Your customer opens the link, scans the QR (or runs Meta Embedded Signup), and the number connects to your account.
Pairing Link modal with the hosted connect link

A remote pairing session — send the hosted link to your customer; when they scan the QR, the number.connected webhook fires.

POST /v1/numbers/remote-pairing

Same body as POST /v1/numbers, plus pairing-specific options:
Response 201:
Differences from POST /v1/numbers:
  • The instance is created in CLOSE state (disconnected) — no QR code is returned.
  • remotePairingUrl is the public link for the end customer. The endpoint only hands the link back — you deliver it to your customer yourself (your own UI, email, chat, wherever they are).
  • When the end customer opens the URL and connects, the number.connected webhook fires normally.

linkToApiKey — retired

Accepted but does nothing. Sending it is not an error, and no API key is touched: linkedApiKeyId in the response is always null. It used to re-point a number-scoped key at the number you had just paired, silently unscoping it from the number it was bound to.

warnings on the 201

A successful pairing may come back with a warnings array of strings. It is present only when there is something to report. For provider=PILOT_STATUS, externalRef and redirectUrl are accepted but cannot be honored: they ride the Meta signed session, and the QR pairing link carries no session. Each one you send is reported in warnings — and the pairing still succeeds. It is not a 400:
They used to be discarded in silence. If you need either of them, use provider=META — the Meta branch is the one that carries them through the signed session. The body also accepts an optional branding object to override the connect page’s logo/colors/title for just this link (snapshotted onto the token). It overrides the tenant’s saved branding. See Connect page branding.

Meta numbers: metaFlow

For official Meta Cloud API numbers the pairing link can run Meta flows instead of QR pairing:
  • metaFlow: "embedded" — the hosted page runs Meta Embedded Signup so your customer connects their own WABA without leaving the link.
  • metaFlow: "credentials" — the hosted page collects the customer’s existing WABA credentials. It also shows a route inbound webhooks to Pilot Status checkbox (on by default) that auto-subscribes the customer’s WABA to Pilot’s callback, so no manual webhook setup is needed — see webhook delivery.
Remote pairing with metaFlow is the hosted option. If you already hold the WABA credentials server-side, use POST /v1/numbers/meta (direct BYO-WABA) instead — no link and no end-customer interaction needed.

Errors

Both 402s carry the numbers behind the refusal — plan, maxNumbers, currentNumberCount, extras, proratedTotal, walletBalance and currency — alongside error and code. Branch on the code: the two share a status but not a remedy. See capacity errors.
Fixed: INSUFFICIENT_FUNDS on this route now answers 402, the same status as POST /v1/numbers. It used to come back as a 500.
Changed. A plan whose allowance was simply full used to answer INSUFFICIENT_FUNDS here too, and the body carried nothing but the code repeated in both fields. It now answers PLAN_NUMBER_LIMIT_REACHED, with the capacity figures attached.

Public token endpoints (no authentication)

The pairing page uses these token-based endpoints — you can also call them to build your own connect UI: Notes:
  • The token expires after 24 hours or upon successful connection (single-use).
  • POST .../connect only works when the state is not OPEN.
  • The same connection state shown in the dashboard and the webhooks (number.created, number.connected) apply.