Skip to main content

Criar, conectar e excluir números

Crie um número de WhatsApp via API pública, conecte-o (QR code ou código de pareamento) e exclua-o quando não for mais necessário.
Use uma chave de API com escopo de tenant (recomendada para plataformas SaaS que gerenciam múltiplos números). Uma chave com escopo de número também funciona — ela continua presa ao número que já cobre. Autentique com x-api-key: ps_....

POST /v1/numbers — Criar um número

string
obrigatório
Nome de exibição do número.
string
obrigatório
O número de telefone no formato E.164 (ex.: +5511999999999).
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 que você acabara de criar, tirando-a silenciosamente do número ao qual estava presa.
A resposta inclui qrcodeBase64 e pairingCode (código de pareamento por letras do WhatsApp; pode ser null se o provedor não retornar um). Mostre o QR code para a pessoa dona do telefone, ou deixe-a digitar o código de pareamento.
Chame estes endpoints apenas a partir do seu backend — nunca exponha sua chave ps_ no navegador.

Números Meta (API oficial da Cloud)

POST /v1/numbers cria um número não oficial (pareado por QR). Para números oficiais da Meta Cloud API, use um dos fluxos Meta em vez disso:
  • POST /v1/numbers/meta — BYO-WABA direto: traga suas próprias credenciais de WABA, ou
  • Meta Embedded Signup hospedado via um link de pareamento remoto com metaFlow.

POST /v1/numbers/meta — traga sua própria WABA

Provisiona um número oficial da Meta Cloud API a partir de credenciais de WABA que você já possui. Este fluxo é para plataformas que já controlam a WABA e têm um token de system user. Se você não tem essas credenciais, use o Embedded Signup hospedado via um link de pareamento remoto com provider=META. Exige uma chave de API com escopo de tenant.
string
obrigatório
Nome de exibição do número (1–60 caracteres).
string
obrigatório
O número de telefone em dígitos, com + inicial opcional.
string
obrigatório
O phone number ID da Meta do telefone da WABA.
string
obrigatório
O ID da WhatsApp Business Account (WABA).
string
obrigatório
Um token de acesso de system user com acesso à WABA.
string
obrigatório
O app secret do seu app Meta.
string
obrigatório
O ID do seu app Meta.
boolean
padrão:"false"
Quando true, a Pilot Status inscreve sua WABA no próprio callback de webhook dela (definindo o override_callback_uri da Meta mais um verify token por número), de modo que as mensagens recebidas cheguem à Pilot automaticamente — você nunca cola uma URL de webhook no seu Meta App Dashboard. A resposta então retorna webhook.routedToPilot: true.Padrão false. O override é um valor único por WABA, então habilitá-lo redireciona todos os números daquela WABA para longe do callback que seu app usa atualmente (por exemplo, seu próprio backend ou um Chatwoot existente). Só ative quando quiser que a Pilot Status seja a dona da entrega de webhooks dessa WABA.
Aposentado — aceito, mas não faz nada, exatamente como no POST /v1/numbers acima. linkedApiKeyId na resposta é sempre null.
Erros:
  • 400 — erro de validação (campos do corpo ausentes ou inválidos).
  • 402 PLAN_NUMBER_LIMIT_REACHED — a cota de números do seu plano está cheia. No plano Free, adicionar créditos não resolve: libere um slot, compre um número extra por conta própria ou suba de plano. Em um plano pago, só é respondido quando você nunca comprou um número extra e o próximo não pode ser custeado.
  • 402 INSUFFICIENT_FUNDS — só nos planos pagos: o número seria um extra pago e não há saldo na carteira nem cartão salvo.
  • 403 NUMBERS_GRANT_NOT_ALLOWED — grants OAuth por número não podem provisionar números.
  • 409 — “Number already exists” (o número já existe).

Erros de capacidade e como resolver

As duas rotas de provisionamento desta página (POST /v1/numbers e POST /v1/numbers/meta) checam capacidade antes de gravar a linha do número, e as duas recusam com 402. O status sozinho não diz o que fazer — o campo error diz. Nestas duas rotas o discriminador vem só em error; o POST /v1/numbers/remote-pairing manda os mesmos valores em error e em code. O corpo traz os números por trás da recusa, para você não ter de adivinhar:
Mudou. Um plano cuja cota estava simplesmente cheia também respondia INSUFFICIENT_FUNDS — então uma conta com um número num plano de um número era informada de que estava sem dinheiro, e ia atrás de um saldo que nunca foi o problema. O status não mudou (402); o que é novo é o valor em error, e os campos que vêm junto.

Entrega de webhook (mensagens recebidas)

O envio funciona assim que o número é criado — não depende do webhook. Para a Pilot Status também receber mensagens, a Meta precisa entregar os webhooks dessa WABA para a Pilot. A resposta traz um objeto webhook justamente para isso:
Duas formas de conectar:
  • Automática — passe routeWebhooksToPilot: true na requisição. A Pilot inscreve a WABA para você e a resposta retorna webhook.routedToPilot: true; nada mais a configurar.
  • Manual — no seu Meta App Dashboard, defina a Callback URL do produto WhatsApp como webhook.url e o Verify token como webhook.verifyToken.
A página de conexão hospedada metaFlow: "credentials" (veja pareamento remoto) expõe a mesma escolha como um checkbox.

GET /v1/numbers//connect — Regenerar o QR code

Gera um novo QR code e código de pareamento quando a instância não está OPEN.
  • A resposta inclui qrcodeBase64 e pairingCode novos.
  • Se o número já estiver conectado (OPEN), o endpoint retorna 409 — não há nada para parear.
  • Plano Free: quando a cota do plano já está cheia e este número nunca conectou, o endpoint retorna 402 com { "error": "PLAN_NUMBER_LIMIT_REACHED", "code": "PLAN_NUMBER_LIMIT_REACHED", "message": "…", "plan": "FREE", "maxNumbers": 1, "currentNumberCount": 1 }, e nenhum QR code é gerado. O message é uma frase bilíngue, English | Português. Reparear um número que já tinha conectado nunca é recusado. Veja Plano Free.
  • Não se aplica a números Meta (eles não usam pareamento por QR).
  • Reflete o mesmo estado de conexão que a página de Números no painel.

DELETE /v1/numbers/ — Remover um número

É um soft delete de 30 dias, não uma exclusão definitiva:
  • O aparelho pareado é desconectado na hora — o número para de enviar e receber.
  • O número em si (id, API keys, webhooks, histórico de mensagens) fica guardado até restorableUntil e depois é apagado de vez por um job.
  • Enquanto está nessa janela, criar o mesmo telefone de novo com POST /v1/numbers devolve 409 NUMBER_SOFT_DELETED (o corpo traz o numberId antigo). Restaure-o, ou purgue antes.
Cobrança: no Pay As You Go, número excluído não é cobrado na próxima virada — purgado ou não. Nos outros planos, excluir não reduz a capacidade paga; para pagar por menos números extras, agende uma redução.

POST /v1/numbers//restore — Desfazer a exclusão

Traz o número de volta dentro da janela de 30 dias, com o mesmo id, API keys, webhooks e histórico. Restaura o registro, não a conexão — o aparelho foi desconectado na exclusão, então reconecte depois com GET /v1/numbers/{id}/connect (ou reprovisione um número Meta). Uma restauração bem-sucedida emite number.restored para os webhooks do número.
  • 404 com code: RESTORE_WINDOW_EXPIRED depois dos 30 dias.
  • 409 NUMBER_ALREADY_ACTIVE quando o mesmo telefone foi reconectado nesse meio-tempo — use o número ativo.
  • Restaurar um número que já tinha conectado pode cobrar. Esse número volta a entrar na sua contagem de números. Se isso leva o workspace acima da capacidade que ele já pagou, um número extra é cobrado no restore, com prorata do resto do ciclo. Quando isso não pode ser pago, a resposta é 422 INSUFFICIENT_FUNDS (ou PLAN_NUMBER_LIMIT_REACHED) com proratedTotal e walletBalance, nada é cobrado e o número continua excluído. Repetir o mesmo restore nunca cobra duas vezes.
  • Um número que nunca conectou não custa nada para restaurar. Ele ainda não conta, e é cobrado na primeira conexão, como qualquer outro.

DELETE /v1/numbers//purge — Excluir de forma permanente

Irreversível. Purgar destrói o número na hora, com tudo o que depende dele — histórico de mensagens, chats, templates, webhooks e API keys do número — e desregistra na Meta um número oficial. Não há restauração depois.
  • Funciona com um número já excluído com DELETE /v1/numbers/{id} — o fluxo comum é excluir e depois purgar — ou com um ativo.
  • Use quando o mesmo telefone precisa ser criado de novo em seguida (o caso do 409 NUMBER_SOFT_DELETED).
  • Não economiza nada na cobrança em relação ao DELETE.
  • Chame com uma key de tenant. A key presa ao número excluído deixa de autenticar assim que ele é excluído.
  • Com token OAuth / MCP, só o OWNER do workspace pode purgar (403 PERMISSION_DENIED caso contrário).

Webhooks relacionados

  • number.created — dispara quando a instância é criada.
  • number.connected — dispara quando o cliente completa a conexão via QR / pareamento (estado OPEN).
  • number.removed — dispara na exclusão.
  • number.restored — dispara quando um número excluído é restaurado dentro da janela de 30 dias (por esta rota ou pelo painel). O número volta desconectado.
Consulte a referência de eventos de webhook.