Números extras e On Demand
Compre um número extra de WhatsApp pela API pública com uma chave de escopo do tenant. A precificação segue o modelo On Demand: você paga um preço mensal por número conectado (definido por tenant pela equipe da Pilot Status) e obtém mensagens ilimitadas em cada número.
A aba Cartão em Planos — salve um cartão uma vez e números extras comprados via API são cobrados automaticamente (On Demand).
Chaves de escopo de número recebem 403 — use a chave de escopo do tenant (painel Profile → API).
Cobrado na primeira conexão
Um número extra é um número de WhatsApp acima da capacidade que o seu workspace já pagou: a cota do plano, mais os números extras que você comprou, mais os que foram concedidos a você. Ele é cobrado quando o número conecta pela primeira vez — em todo plano, e por qualquer caminho de conexão: o painel, a API, o servidor MCP, um link de pareamento remoto ou o Embedded Signup da Meta.- Criar um número não cobra nada. Gerar um link de pareamento também não.
- Um número que nunca conectou não conta na sua capacidade nem na sua cobrança mensal. Você paga só pelos números que foram de fato pareados.
- Em um plano pago, a cobrança é automática. É a mesma compra de
POST /v1/subscription/extra-numberspara um número: proporcional aos dias que faltam no ciclo, primeiro os créditos da carteira, o restante no cartão salvo. O plano Free nunca compra sozinho — veja Plano Free. - Comprar antes continua funcionando. Um número que conecta dentro da capacidade que você já pagou não é cobrado de novo.
- Em um número não oficial, a primeira conexão é a primeira vez em que o QR Code ou o código de pareamento é concluído. Em um número oficial (Meta Cloud API), é quando o número é ativado — por exemplo, quando o Embedded Signup é concluído.
Uma recusa continua existindo na criação. Em um plano pago, quando o próximo número seria um número extra e o workspace não tem saldo na carteira para cobri-lo nem cartão salvo, criar o número — ou o link de pareamento dele — continua respondendo
402 com INSUFFICIENT_FUNDS ou PLAN_NUMBER_LIMIT_REACHED. No plano Free, um número acima da cota do plano é recusado com 402 PLAN_NUMBER_LIMIT_REACHED, qualquer que seja o saldo. O corpo não mudou: veja erros de capacidade.Plano Free
O plano Free nunca compra um número extra sozinho. Comprar um número extra no Free converte a conta para o On Demand e transforma em pago o número que você já tinha. Isso só acontece pela compra explícita, que pede confirmação: o diálogo de compra do painel, ouPOST /v1/subscription/extra-numbers com confirm: true. Um workspace no Free nunca é convertido nem cobrado por conectar um número.
- Criar um número acima da cota do plano é recusado com
402 PLAN_NUMBER_LIMIT_REACHED, mesmo quando o workspace tem saldo na carteira ou cartão salvo. Nos planos pagos, havendo saldo ou cartão a criação passa, e o extra é cobrado na primeira conexão. - Parear um número que nunca conectou também é recusado quando a cota do plano já está cheia.
GET /v1/numbers/{id}/connect, o passo de conexão de um link de pareamento remoto ePOST /v1/numbers/remote-pairingpara um telefone que já existe respondem402 PLAN_NUMBER_LIMIT_REACHED. Reparear um número que já tinha conectado nunca é recusado. - Se um segundo número conecta mesmo assim — dois pareamentos iniciados ao mesmo tempo — nada é cobrado e o plano não muda. O número continua conectado com o envio bloqueado (
409 NUMBER_BLOCKED,reason: "extra_charge_unpaid"), ePOST /v1/numbers/{id}/payresponde402 PLAN_NUMBER_LIMIT_REACHEDpara ele. Uma recarga ou um cartão salvo não removem esse bloqueio.
POST /v1/numbers/{id}/pay, que responde not_required.
Quando a cobrança é recusada
Se o cartão é recusado ou não há saldo, o número continua conectado, mas o envio por ele fica bloqueado até o pagamento:POST /v1/messages/sendresponde409 NUMBER_BLOCKEDcomreason: "extra_charge_unpaid".- Uma mensagem que já estava na fila falha, e aparece com
NUMBER_BLOCKEDnos logs. GET /v1/numberseGET /v1/numbers/{id}mostramextraChargeUnpaidSinceno número.
Uma cobrança que não pôde ser concluída não é uma recusa. Quando o processador de pagamento está fora do ar, nada é bloqueado: o número continua enviando, e a cobrança é retentada automaticamente a cada 15 minutos.
O que remove o bloqueio
Se a renovação do próprio plano está em atraso, a recarga ou o cartão salvo pagam primeiro a renovação.
No plano Free nenhuma das quatro vale: veja Plano Free.
O bloqueio também sai sozinho, em até 15 minutos, quando a sua capacidade passa a cobrir o número — por exemplo, depois que você compra um número extra com
POST /v1/subscription/extra-numbers.
Depois de 7 dias sem pagamento
- Um número conectado por QR Code que fica 7 dias sem pagamento é desconectado: o aparelho é deslogado e o número deixa de contar na sua capacidade. Um lembrete é enviado 2 dias antes, e o
extraChargeDisconnectAtdo número diz quando. Conectá-lo de novo é uma nova primeira conexão, cobrada de novo. - Um número da Meta Cloud API nunca é desconectado. Ele fica bloqueado para envio até o pagamento.
GET /v1/subscription/extra-numbers — Prévia (dry-run)
proratedTotal é o que você paga agora; monthlyTotalBRL é o que passa a ser cobrado a cada ciclo:
Você só paga pelos dias que faltam no ciclo. A primeira cobrança é proporcional:
proratedUnitPrice = unitPriceMonthly × (remainingDays / totalDaysInCycle). No exemplo acima falta metade do ciclo, então são 2 números × R$14,95 = R$29,90 agora, e R$59,80/mês a partir do próximo ciclo.fundingSource diz como a cobrança será coberta — credits (a carteira cobre todo o proratedTotal), credits+card (parte em créditos, o resto no cartão salvo), card ou none. none significa que a carteira não cobre o proratedTotal e não há cartão salvo (hasSavedCard: false): canFund vem false, e o POST responde 402 INSUFFICIENT_FUNDS sem cobrar nada. Ele não devolve link de checkout — recarregue a carteira ou salve um cartão antes (POST /v1/billing/checkout, abaixo).
POST /v1/subscription/extra-numbers — Comprar
- Conversão Free → On Demand. Se você está no plano Free, comprar um número extra move você para o On Demand: seu número atual (antes gratuito, limitado a 200 mensagens) se torna um número pago e ilimitado e o novo número também é cobrado. Portanto, comprar 1 extra estando no Free cobra você por 2 números. Como isso altera o que você paga, o
POSTretorna 409CONFIRMATION_REQUIRED(com a prévia) a menos que você envieconfirm: true. - Já no On Demand / pago. Comprar incrementa sua contagem de números; as mensagens permanecem ilimitadas.
- Pagamento. O custo proporcional é cobrado na hora: primeiro da sua carteira pré-paga, e o que sobrar vai no cartão salvo (painel Plans → Cartão, ou
POST /v1/billing/checkoutcomadd_card). Uma compra bem-sucedida responde{ "success": true, "charged": true, … }—creditsUsedecardChargedmostram como a cobrança foi dividida, epaidExtraNumbersjá inclui a vaga nova, então você pode criar o número comPOST /v1/numbersem seguida. Esta rota nunca devolve link de checkout (não existecheckoutUrl, echargednunca vemfalse): sem créditos suficientes e sem cartão salvo, ela retorna402 INSUFFICIENT_FUNDS— nada é cobrado, e os créditos que ela chegou a usar são devolvidos. Recarregue ou salve um cartão e tente de novo. - A recorrência mensal sai da carteira, não de uma assinatura à parte. A cada ciclo,
paidExtraNumbers × preço unitárioé debitado dos créditos, com o cartão salvo como reserva. Recarregue comPOST /v1/billing/checkout(wallet_topup, só cartão) ou pelo painel, onde o PIX também está disponível — dá para rodar On Demand só com créditos de PIX recarregados pelo painel, sem nunca salvar um cartão.
Mantenha créditos ou um cartão salvo disponíveis. Se a cobrança de um ciclo não puder ser paga, você tem 2 dias para adicionar créditos ou atualizar o cartão antes que seus números parem de enviar (o recebimento continua). Adicionar saldo reativa na hora.
Quando o pagamento não passa
POST /v1/subscription/extra-numbers distingue três falhas, e elas não dividem a mesma solução. Decida pelo code, nunca pelo status HTTP: duas das três são 402.
Todos esses corpos trazem
proratedTotal e currency, então dá para mostrar o valor que foi tentado. O INSUFFICIENT_FUNDS traz também walletReason, que nesta rota é sempre NO_CARD.
Este é o corpo de INSUFFICIENT_FUNDS quando os créditos não cobrem a cobrança e não há cartão salvo (o error é uma mensagem legível, em português — decida pelo code):
Nos três casos o número extra não foi adicionado. Seu
paidExtraNumbers continua igual e nenhum slot foi liberado — toda escrita acontece depois de uma cobrança bem-sucedida.O campo declineCode
O PAYMENT_FAILED às vezes traz declineCode. Quando vem, é o próprio código de recusa da bandeira, literal (insufficient_funds, expired_card, card_not_supported, …) — pode ser mostrado ao titular do cartão ou usado para decidir.
⚠️ A ausência dele não diz nada. Um PAYMENT_FAILED sem declineCode é um pagamento que não passou por um motivo que não conseguimos atribuir ao cartão — um rate limit na requisição, uma chave de integração expirada, um payment intent que ficou num estado diferente de sucesso. Não inventamos um código para preencher o campo. Portanto:
- Decida pelo
code: "PAYMENT_FAILED". Ele está sempre presente e sempre significa a mesma coisa. - Use o
declineCodesó para refinar a mensagem quando ele existir. - Nunca leia “sem
declineCode” como “não foi recusa” — e nunca como “o cartão está bom”.
O
declineCode nunca aparece no INSUFFICIENT_FUNDS nem no PAYMENT_PROVIDER_ERROR. Nenhum dos dois é recusa de cartão.A capacidade paga é um direito de 30 dias
Ao comprar números extras, essa capacidade é sua durante todo o ciclo de 30 dias. Duas consequências:- Deletar um número não reduz sua capacidade paga.
DELETE /v1/numbers/<id>libera o slot para você reconectar outro número no mesmo ciclo — sua contagem paga e sua cobrança seguem iguais até o fim do ciclo. - Reduzir a capacidade é uma ação explícita e agendada. Você decide baixar a quantidade de slots pagos; a mudança vale no próximo ciclo, quando a cobrança cai para o novo valor. Nada é estornado do ciclo em andamento.
No Pay As You Go funciona diferente
No Pay As You Go não existe capacidade para comprar de volta nem para agendar redução — você paga pelos números que tem conectados:- O número é cobrado quando conecta pela primeira vez, prorata pelos dias restantes do ciclo — a mesma regra de todos os planos, descrita acima. Para número não-oficial isso é a primeira conexão; para número oficial (Meta), é quando o Embedded Signup é concluído.
- O slot que você pagou vale pelo ciclo. Deletar um número e conectar outro no lugar não cobra de novo.
- O ciclo seguinte cobra só o que continuar conectado. Nada se acumula do ciclo anterior, então não há o que agendar para baixo — veja o
409 NOT_APPLICABLE_FOR_PLANno endpoint abaixo. - Um pareamento que você nunca concluiu não é um número e não é cobrado. A linha “Aguardando conexão”, que aparece enquanto o seu usuário final está no diálogo do Facebook, fica de fora da cobrança e da sua capacidade, e é removida automaticamente 24h depois de criada.
DELETE /v1/subscription/extra-numbers — Agendar uma redução
Agenda a redução dequantity slot(s) pago(s) para o próximo ciclo:
- Agendado, não imediato. Este ciclo mantém a capacidade atual (sem estorno); a redução vale a partir do próximo rollover, quando os meses futuros cobram menos.
- Editável. Chamar de novo sobrescreve o alvo agendado. Cancele com
DELETE …/schedule(abaixo). - Não pode ficar abaixo dos números conectados. Se o alvo deixaria o limite abaixo dos números que você ainda tem conectados, retorna 409
NUMBER_LIMIT_EXCEEDED({ currentNumberCount, maxNumbers }) — delete um número antes. - Não existe no Pay As You Go. Retorna 409
NOT_APPLICABLE_FOR_PLAN. Não há capacidade paga a devolver: o Pay As You Go cobra pelos números que você tem conectados, e o próximo ciclo já cobra apenas o que continuar conectado. Para pagar menos, delete o número — não é preciso agendar nada. quantitytem default1e é limitado para nunca ficar abaixo de0extras pagos. Chaves de escopo de número recebem 403.
paidExtraNumbers continua no valor do ciclo atual; scheduledPaidExtraNumbers é o alvo que passa a valer no próximo ciclo:
DELETE /v1/subscription/extra-numbers/schedule — Cancelar a redução agendada
Cancela uma redução pendente para que o próximo ciclo mantenha sua capacidade paga atual. No-op se nada estiver agendado.POST /v1/billing/checkout — Recarga de carteira / adicionar um cartão
Gera uma URL de checkout hospedada para ações de cobrança:purpose: "wallet_topup"— recarrega a carteira pré-paga. Só cartão: o checkout hospedado do Stripe não oferece PIX — recarga por PIX existe só pelo painel (contas em BRL). Exigeamount: um número positivo, na moeda da sua conta (a da carteira,BRLouUSD— não dá para escolher por requisição). Ausente, zero, negativo ou não numérico retorna400{ "error": "amount must be a positive number", "code": "INVALID_AMOUNT" }.purpose: "add_card"— salva um cartão para futuras cobranças On Demand.
url para abrir no navegador. No wallet_topup ela traz também orderId, amount e currency: