Pareamento remoto — link de pareamento hospedado
Para plataformas SaaS que gerenciam números para clientes finais, o Pareamento Remoto permite gerar um link de pareamento em vez de exibir o QR code você mesmo. Seu cliente abre o link, escaneia o QR (ou executa o Meta Embedded Signup), e o número conecta à sua conta.
Uma sessão de pareamento remoto — envie o link hospedado ao seu cliente; quando ele escanear o QR, o webhook number.connected dispara.
POST /v1/numbers/remote-pairing
Mesmo corpo dePOST /v1/numbers, mais opções específicas de pareamento:
201:
POST /v1/numbers:
- A instância é criada no estado
CLOSE(desconectada) — nenhum QR code é retornado. remotePairingUrlé o link público para o cliente final. O endpoint apenas devolve o link — a entrega ao cliente é sua (sua própria interface, e-mail, chat, onde ele estiver).- Quando o cliente final abre a URL e conecta, o webhook
number.connecteddispara normalmente.
linkToApiKey — aposentado
Aceito, mas não faz nada. Enviá-lo não é erro, e nenhuma chave de API é alterada: linkedApiKeyId na resposta é sempre null. Ele reapontava uma chave com escopo de número para o número recém-pareado, tirando-a silenciosamente do número ao qual estava presa.
warnings no 201
Um pareamento bem-sucedido pode voltar com um array warnings de strings. Ele só aparece quando há algo a relatar.
Para provider=PILOT_STATUS, externalRef e redirectUrl são aceitos mas não podem ser honrados: eles viajam na sessão assinada da Meta, e o link de pareamento por QR não carrega sessão nenhuma. Cada um deles é relatado em warnings — e o pareamento continua dando certo. Não é um 400:
provider=META — é o ramo Meta que os leva adiante na sessão assinada.
Histórico: decida nesta chamada
Quem abre o link conecta na hora, e o provider entrega o histórico do aparelho logo em seguida — uma vez só. Não existe um momento no meio para umPATCH, então esta rota aceita o bloco settings das configurações do número, nos dois providers:
201 para META:
settings.historyImportEnabledtem padrãotrue. Omita o bloco para manter o histórico do aparelho; mandefalsepara descartá-lo.numberIdé a linha provisória em que a conexão vai cair. Use-o para acompanhar a conexão (GET /v1/numbers/{id}/status) ou para darPATCHantes de a pessoa terminar.- Um bloco inválido responde
400 INVALID_SETTINGSe nada é criado. - No
PILOT_STATUS, o bloco só é aplicado quando esta chamada cria o número.
Marca por link (white-label)
O corpo também aceita um objeto opcionalbranding para sobrescrever o logo/cores/título da página de conexão para apenas este link (registrado no token). Ele sobrepõe a marca salva do tenant. Veja Marca da página de conexão.
Números Meta: metaFlow
Para números da API oficial Meta Cloud o link de pareamento pode executar fluxos Meta em vez do pareamento por QR:
metaFlow: "embedded"— a página hospedada executa o Meta Embedded Signup. Quem abrir o link autentica no Facebook dentro do diálogo da própria Meta e escolhe ali o business portfolio e o número de telefone.metaFlow: "credentials"— a página hospedada coleta as credenciais de uma WABA existente. Ela também exibe um checkbox rotear webhooks recebidos para a Pilot Status (ligado por padrão) que inscreve automaticamente essa WABA no callback da Pilot, dispensando qualquer configuração manual de webhook — veja entrega de webhook.
Quem autentica decide de quem é a WABA
A página hospedada executa o mesmo componente de Embedded Signup que o painel executa, com o mesmo app e a mesma configuração. Nada no token de pareamento fixa um business portfolio. Ou seja: a WABA nasce no portfólio de quem fizer login no Facebook naquele diálogo — o cliente final, se ele abrir o link, ou você, se um operador do seu time abrir e selecionar o seu próprio portfólio. Se o seu modelo é “a WABA é nossa e nós pagamos a Meta”, faça o seu operador rodar o link; se é “o cliente é dono da WABA dele”, mande o link para o cliente. A chamada de API é idêntica nos dois casos.O Embedded Signup aqui é configurado com
featureType: "whatsapp_business_app_onboarding" — o onboarding de coexistência da Meta. O diálogo exibe o QR que o dono do número escaneia com o app WhatsApp Business no celular dele, então o telefone ainda precisa estar ao alcance naquele momento, seja quem for que estiver conduzindo o diálogo.POST /v1/numbers/meta — a alternativa BYO-WABA
Se você já tem metaPhoneId + metaWabaId + um token de system user no servidor, o POST /v1/numbers/meta anexa o número sem link e sem interação do cliente final.
Ele é agnóstico quanto a coexistência — anexa um número em coexistência e um número Cloud API puro do mesmo jeito. O que ele não faz é nada do que o Embedded Signup faz por você:
Validade do link: dois TTLs diferentes
Os dois provedores emitem duas credenciais diferentes, e elas não expiram no mesmo relógio.
Leia o
expiresAt do 201 em vez de fixar qualquer um dos dois números no código. Num link META, o número também aparece imediatamente como placeholder cujo GET /v1/numbers/{id}/status responde PENDING e depois EXPIRED — é esse o sinal para mostrar ao seu cliente a mensagem de “o link expirou” e emitir um novo.
A origem da página de conexão (postMessage)
Quando você embute a página de conexão no seu próprio site, ela conversa com a página hospedeira por postMessage (connect:paired, connect:error, connect:expired). Os dois provedores usam o mesmo host — ele vem de uma única configuração da plataforma, não do provedor — e em produção esse host é:
Melhor do que fixar no código: derive-a do link que a API acabou de devolver —
new URL(response.remotePairingUrl).origin. O host é uma configuração de deploy; um receptor preso a um literal quebra em silêncio se ela mudar, enquanto um derivado do remotePairingUrl não tem como divergir.Erros
Os dois
402 trazem as figuras por trás da recusa — plan, maxNumbers, currentNumberCount, extras, proratedTotal, walletBalance e currency — ao lado de error e code. A recusa do plano Free para um telefone que já existe traz só plan, maxNumbers e currentNumberCount. Ramifique pelo código: os dois compartilham o status, mas não a solução. Veja erros de capacidade.
Corrigido:
INSUFFICIENT_FUNDS nesta rota agora responde 402, o mesmo status do POST /v1/numbers. Antes vinha como 500.Mudou. Um plano com a cota simplesmente cheia também respondia
INSUFFICIENT_FUNDS aqui, e o corpo não trazia nada além do código repetido nos dois campos. Agora responde PLAN_NUMBER_LIMIT_REACHED, com as figuras de capacidade junto.Endpoints públicos por token (sem autenticação)
A página de pareamento usa estes endpoints baseados em token — você também pode chamá-los para construir sua própria UI de conexão:
Observações:
- Plano Free: quando o workspace que emitiu o link está no Free, a cota dele já está cheia e este número nunca conectou,
POST /v1/remote-pairing/{token}/connectresponde402com{ "error": "PLAN_NUMBER_LIMIT_REACHED", "code": "PLAN_NUMBER_LIMIT_REACHED", "message": "…", "plan": "FREE", "maxNumbers": 1, "currentNumberCount": 1 }, e nenhum QR code é gerado. Omessageé uma frase bilíngue,English | Português. Quem está com o link não tem como resolver: o workspace precisa comprar um número extra ou subir de plano. Veja Plano Free. - Este é o token
PILOT_STATUS(QR): expira após 24 horas ou mediante conexão bem-sucedida (uso único). Um linkMETAde Embedded Signup é uma credencial diferente, com TTL de 30 minutos — veja Validade do link. POST .../connectsó funciona quando o estado não éOPEN.- O mesmo estado de conexão exibido no painel e nos webhooks (
number.created,number.connected) se aplica.