Ir para o conteúdo
Documentação Ir para o painel
O que a Zera não faz

A lista das ausências deste produto

Cada item desta página foi conferido no código que está no ar, e vem com o endereço para você conferir também. O que a Zera não conseguiu medir não entrou. Vale a pena ler isto antes de escrever a primeira linha do seu lado: descobrir aqui custa cinco minutos, descobrir com o código meio escrito custa um dia.

A maior de todas: você não consegue validar a assinatura dos eventos que recebe.

Todo POST da Meta chega com o cabeçalho X-Hub-Signature-256, calculado com o segredo do aplicativo inscrito na sua conta. Esse aplicativo é o da Zera, o segredo é um só para todos os clientes, ele não vai na credencial e não vai passar a ir. É a única ausência desta página que você não contorna sozinho. O que dá para fazer no lugar está em Receber mensagens.

A ausência que estava aqui até 22 de setembro de 2026 saiu: o campo de webhook deixou de ser só uma anotação nossa. Desde 23 de setembro, com a escrita ligada em produção, o salvamento aponta a sobreposição no seu número dentro da Meta, desde que a conexão do número esteja concluída. O código que faz isso existe desde 15 de setembro, e até o dia 22 ficou desligado. O que ainda não existe é medição com um número real, e a página de recebimento diz isso com todas as letras.

Como ler esta página

Cada ausência vem em três blocos curtos, sempre na mesma ordem. O que não acontece é o fato. Por que é onde isso foi medido, com o arquivo e, quando existe, o nome da constante, da chave ou da função, para você conferir por conta própria se um dia desconfiar. Muitas citações trazem também um número de linha, e ele é o da data em que aquele item foi medido: linha anda a cada commit, e várias já andaram. Quando o número não bater, procure pelo nome, que é o endereço que não muda. O que você faz no lugar é o caminho que existe hoje.

Sem rodeio e sem desculpa: quando o certo é dizer que a Zera não sabe, a página diz que não sabe.

A lista, numa tela

A tabela é o resumo, e as seções numeradas abaixo trazem o detalhe e a saída. Algumas seções cobrem mais de uma linha da tabela, e as duas últimas, sobre coexistência e revisão de conteúdo, não têm linha nela.

O que a Zera não faz, e onde cada ausência foi medida no código
O que não existeOnde isso foi medido
Validar a assinatura dos eventos do webhook META_APP_SECRET é uma variável só do ambiente, usada em _es-executor.js para toda conta: o segredo é da Zera e é o mesmo para todos os clientes
Editar ou apagar um modelo de mensagem pelo painel Criar modelo de texto existe desde 24/08/2026 (modelo-novo.js, só o componente BODY), e ler a lista também (modelos.js, com teto de 100 na constante LIMITE). Não existe PUT nem DELETE de modelo em functions/
Conferir se o seu token pode enviar _es-executor.js:338 confere só whatsapp_business_management
Sua mensagem passar por um servidor nosso Nenhum POST /{phone_number_id}/messages em functions/
Ambiente de teste, número de mentira, caixa de areia As quatro rotas de conexão em _es.js:57 são todas de número real
Guardar mensagem, entrega ou leitura, no plano da API atividade.js:52 lê só mudança de estado, com teto de 100 em atividade.js:30
Escrever custo quando a Meta não devolve o valor O custo é lido de verdade em metricas.js, e quando a Meta não devolve o valor a resposta traz o motivo em custo.situacao (metricas.js:185). Nenhum zero entra no lugar.
Converter o custo para real O valor vai para a tela na moeda em que a Meta cobra a conta, lida no campo currency da própria conta. Sem moeda, o número não é escrito.
Separar as métricas por número metricas.js:73: a analítica, custo inclusive, é da conta inteira
Uma API do painel, com chave _hub.js:85 exige o cookie de sessão, e nenhuma rota do painel lê cabeçalho de autorização
A coluna do motivo da recusa aparecer sempre Ela só nasce quando algum modelo trouxe motivo (a bandeira temMotivo de hub-canal.js), e a leitura pode voltar sem ela (modelos.js:168)
Enviar a foto do perfil pelo painel escrever o perfil existe desde 01/09/2026 (perfil-salvar.js: sobre, descrição, e-mail, endereço, dois sites e categoria) e a foto aparece desde 02/09/2026 (foto.js serve os bytes pela nossa origem). Enviar uma foto nova continua fora: exige o caminho de upload da Meta, com outra autorização
Ler health_can_send e name_status _saude-meta.js:28, e as duas células em _canal.js:98 e :100
Vigiar a saúde do seu número sozinho A leitura só sai quando alguém aperta o botão, com freio em saude.js:58
Gerar outra credencial ou revogar a atual O cabeçalho de credencial.js, e o teto de três exibições a cada 24 horas em TETO_POR_DIA e JANELA_DO_TETO
Trocar de número ou acrescentar um pelo painel O único INSERT INTO canal_whatsapp do produto é _lib.js:411, no cadastro
Migrar de outro fornecedor com botão _es.js:155: a rota outra_api é marcada sem autoatendimento

1. Você não valida a assinatura dos eventos

O que não acontece. Você não tem como provar, por criptografia, que um POST que chegou no seu endereço de webhook veio mesmo da Meta. O cabeçalho X-Hub-Signature-256 chega, e a chave que o verifica não é sua.

Por que. Essa assinatura é um HMAC SHA-256 do corpo cru, calculado com o segredo do aplicativo que está inscrito na sua conta de WhatsApp. Esse aplicativo é o da Zera, e o segredo dele é META_APP_SECRET, uma variável só do ambiente, usada em _es-executor.js para toda conta de todo cliente. Ou seja, é o mesmo segredo para todo mundo. Entregá-lo na credencial acabaria com ele no primeiro vazamento, e o estrago não seria só de quem vazou.

O que você faz no lugar. Quatro defesas, todas descritas em Receber mensagens: um endereço com caminho longo e aleatório, em https; recusar todo GET de verificação que não trouxer exatamente um dos códigos de verificação dos números que apontam para aquele endereço, porque cada número tem o seu; casar o wamid de cada evento com algum envio ou conversa que você conhece antes de confiar nele; e confirmar na Graph, com a sua credencial, antes de disparar qualquer coisa cara. Se a validação de assinatura for exigência do seu lado, escreva para a Zera antes de começar: é um caso para conduzir junto, e não um caso para você contornar sozinho.

1.1. O que estava aqui e saiu: o webhook que ninguém apontava

Até 22 de setembro de 2026 esta era a ausência número um da página: o campo de webhook guardava o endereço no nosso banco e o produto não o mandava para a Meta: até 15 de setembro não havia código para isso, e de 15 a 22 de setembro o código existia e estava desligado. Ela deixou de existir, e este item fica no lugar dela para quem voltar aqui atrás da frase antiga.

O que mudou. Em 15 de setembro de 2026 nasceu hub/canal/_webhook-meta.js, o motor que aponta o override no número (POST /{phone_number_id} com webhook_configuration) e relê para gravar o desfecho verdadeiro. Em 23 de setembro de 2026 a variável ZS_WEBHOOK_META_ESCREVE foi gravada com valor 1 no projeto Pages zera-app, e a escrita passou a acontecer em produção.

O que não mudou. O POST /{waba_id}/subscribed_apps de PASSOS.assinar_app continua existindo e continua sendo feito sem corpo: ele assina o aplicativo na conta, e é outra coisa. No plano com caixa de entrada, o endereço da caixa é registrado pelo Chatwoot na criação da caixa (_chatwoot.js, criaInbox), no nível da conta. A Zera ainda não mediu se ele sobrevive à assinatura sem corpo que a reconexão refaz. A rota do painel recusa a troca nesse plano com 409 plano_com_inbox.

A outra porta que aponta. Além do salvamento no painel, a rotina de operação admin/webhook-reaplicar.js, quando a operação da Zera a executa, pode apontar na Meta o endereço guardado de um número conectado, sem caixa de entrada, que nunca foi confirmado ou cujo endereço confirmado não é o guardado. Isso inclui o endereço da ficha e o salvamento cujo e-mail de aviso não saiu. Ela chama o mesmo motor, sem o e-mail ao dono e sem devolver o código de verificação: quando é ela que gera o código, ele só aparece na exibição da credencial, que o desenha logo abaixo do token, com botão de copiar próprio.

A honestidade que sobra, e ela importa. Nenhum número passou por esse caminho de ponta a ponta em produção até hoje. A escrita tem prova em código e está ligada; o que não existe é medição com um número real. Se você for o primeiro, escreva para a Zera ao terminar, dando certo ou dando errado.

2. O escopo que faz o envio funcionar não é conferido

O que não acontece. A conexão do seu número não verifica se o token que ela guardou carrega whatsapp_business_messaging, que é o escopo do qual POST /{phone_number_id}/messages depende. Você pode terminar a conexão com tudo verde no painel e tomar recusa no primeiro envio.

Por que. Em _es-executor.js:338, a rotina procura, dentro dos escopos que a Meta devolve, apenas whatsapp_business_management, e usa isso para descobrir qual conta de WhatsApp o token alcança. A palavra whatsapp_business_messaging não aparece em nenhuma linha de código deste projeto: procurando em functions/ e em public/js/, o resultado é zero, e as ocorrências que existem são frases desta documentação, esta inclusive. Quais escopos o fluxo PEDE não dá para conferir aqui: eles são configuração do Embedded Signup do lado da Meta, atrás do META_CONFIG_ID (_es.js:214), que não está no repositório. Esta página não afirma que o seu token tem o escopo de envio, nem que não tem: ela afirma que nada do nosso lado verifica.

O que você faz no lugar. Mande a primeira mensagem para o seu próprio celular antes de construir qualquer coisa em cima. Se voltar erro 200, o caminho é reconectar o número pelo painel, e não tentar outro formato de corpo. O que cada código quer dizer está em Erros.

3. A Zera não é intermediária, e isso tem consequência

O que não acontece. No plano da API, nenhuma mensagem sua passa por um servidor da Zera. Você chama https://graph.facebook.com/v25.0 direto, com o seu token, e a Zera não vê o conteúdo, não consegue reenviar o que falhou, não consegue depurar a sua chamada por dentro e não tem registro do que você mandou.

Por que. Não existe POST /{phone_number_id}/messages em lugar nenhum de functions/. O único /messages do repositório é a API interna do Chatwoot, em botsync/entrada.js:254, que serve o plano de caixa de entrada e não é a Cloud API. O endereço base é GRAPH_BASE em _es.js:37 e a versão é GRAPH_PADRAO em _es.js:28. Nenhuma das chamadas que o produto faz com o seu token envia mensagem. Elas são os passos da conexão, as leituras do painel e quatro escritas, cada uma com o seu gatilho:

  • Salvar o perfil do número, quando você salva na aba Perfil: POST /{phone_number_id}/whatsapp_business_profile, em perfil-salvar.js.
  • Criar um modelo de texto, quando você cria na aba Modelos: POST /{waba_id}/message_templates, em modelo-novo.js.
  • Apontar o endereço do webhook no número, quando você salva o endereço na aba Detalhes com a conexão concluída: POST /{phone_number_id} com webhook_configuration, seguido da releitura, no motor hub/canal/_webhook-meta.js, que decifra o seu token do cofre para isso. A mesma escrita pode ser refeita pela rota de operação da Zera (admin/webhook-reaplicar.js), sempre com o endereço que você salvou e nunca no plano com caixa de entrada.
  • Tirar a inscrição do aplicativo da Zera da sua conta, no encerramento do contrato: descrito na última seção desta página.

O que você faz no lugar. Trate o limite de chamadas como um contrato entre você e a Meta, porque é isso que ele é: o teto que aparece nos códigos 4, 613 e 80007 é do seu token, não de uma fila nossa. Guarde o wamid de todo envio e a resposta crua da Meta no seu próprio registro. Sem isso, quando algo der errado, não existe do nosso lado uma cópia para consultar.

4. Não existe ambiente de teste

O que não acontece. A Zera não tem número de mentira, caixa de areia nem conta de homologação. O seu primeiro envio sai de um número de produção seu, para uma pessoa de verdade, com o custo da Meta cobrado direto de você.

Por que. As quatro rotas de conexão que o produto conhece estão declaradas em _es.js:57: número novo, número que está no aplicativo pessoal, coexistência com o WhatsApp Business e migração de outro fornecedor. Todas terminam num número real, dentro de uma conta de WhatsApp real. Não existe uma quinta rota, e nenhum campo do produto marca um canal como de teste.

O que você faz no lugar. Mande a primeira mensagem para o seu próprio celular, a partir dele, para abrir a janela de conversa antes. O passo a passo está em O primeiro dia, e a regra da janela está em A janela de 24 horas.

5. No plano da API, a Zera não guarda mensagem nem entrega

O que não acontece. Não existe histórico de mensagens no painel do plano de API. Não existe métrica de entrega por mensagem. E os números que aparecem, custo inclusive, são da sua conta de WhatsApp inteira, não deste número.

Por que. A rota da aba de atividade lê a tabela de transições de estado do canal, e só ela, com teto de cem linhas: atividade.js:30 e atividade.js:52. A aba junta a essa lista as datas das últimas exibições de credencial, que vêm da rota do canal (canal/[id].js:136, com teto de dez no LIMIT de SQL_REVELACOES, em credencial.js) e são coladas na tela pelo navegador (a função eventosComCredencial de hub-canal.js). Data de exibição de credencial e mudança de estado é tudo o que essa aba guarda. As métricas vêm ao vivo da Meta, no período que você escolhe na aba, entre sete, trinta e noventa dias (metricas.js:101). Numa chamada só, a Zera lê três coisas: o volume de mensagens, o custo aproximado quebrado por categoria de cobrança e a moeda em que a Meta cobra a sua conta. O custo tem uma regra dela: a Meta não devolve valor para a conta que é cobrada pela linha de crédito de um parceiro, e nesse caso a aba escreve o motivo em vez de desenhar zero (metricas.js:185). A soma é da conta e não do número, o que está escrito em metricas.js:73, e a resposta devolve a lista de números que a Meta somou para a tela poder dizer isso. Cada leitura fica em cache por dez minutos, por combinação de período e detalhe (_leitura-viva.js:70), com teto de vinte por hora por conta e por aba (_leitura-viva.js:82 e :290) e espera de sessenta segundos entre dois cliques em atualizar (_leitura-viva.js:78).

O que você faz no lugar. Guarde tudo do seu lado. O wamid de cada envio, o corpo de cada evento de status que chegar no seu webhook, e a data. O número que vale para a sua contabilidade é o da fatura da Meta, nunca um gráfico de painel.

6. O painel não tem API

O que não acontece. Não existe chave de API da Zera, nem endpoint que a sua máquina possa chamar para ler canais, credenciais, modelos ou métricas. Tudo o que o painel mostra só é alcançável por um navegador com sessão iniciada.

Por que. Todas as rotas do painel passam por abreHub, em _hub.js:85. Ela exige o cookie de sessão, que é HttpOnly, Secure e SameSite=Lax (_lib.js:1239), e por isso não viaja num pedido nascido em outro site. Em toda escrita, ela ainda recusa o pedido que se identifica como vindo de fora: Sec-Fetch-Site diferente de same-origin ou de none, ou Origin diferente da nossa (_hub.js:91 a :100). Quem segura a porta é o cookie; a conferência de origem é o segundo cinto. E não existe cabeçalho de autorização em nenhuma rota do painel: procurando por Authorization em functions/api/hub/, as únicas ocorrências são as chamadas que o servidor faz à Meta.

O que você faz no lugar. Automatize contra a Meta, não contra a Zera. Tudo o que interessa a um programa (enviar, listar modelos, ler perfil, ler saúde, ler analítica) está na Cloud API, com o seu token, e o contrato de cada chamada está em Referência.

7. A coluna do motivo da recusa nem sempre existe

O que não acontece. A tabela de modelos do painel não tem uma coluna de motivo permanente. Ela nasce numa leitura e pode não nascer na seguinte, e a ausência dela não quer dizer que a Meta deixou de informar o motivo.

Por que. São duas ausências diferentes, e a tela separa as duas de propósito. A primeira: a coluna só é criada quando algum modelo daquela leitura trouxe motivo (a bandeira temMotivo de hub-canal.js), porque uma coluna sempre vazia afirmaria que a Meta não deu motivo para nenhum. A segunda: a rota pede rejected_reason junto dos outros campos e, se a Meta recusar o campo com erro 100, ela repete a leitura sem ele uma única vez (modelos.js:122 a :124) e devolve motivo_disponivel: false (modelos.js:168). Nesse caso a tabela volta inteira, sem a coluna, e a tela escreve embaixo que aquela leitura não trouxe o motivo (a frase modelos_motivo_indisponivel).

O que você faz no lugar. Se a coluna não estiver lá e você precisar do motivo naquele instante, leia direto da Meta, com o seu token: GET /{waba_id}/message_templates?fields=name,status,rejected_reason. Os valores documentados são NONE, ABUSIVE_CONTENT, INCORRECT_CATEGORY, INVALID_FORMAT, SCAM, TAG_CONTENT_MISMATCH e PROMOTIONAL, e NONE quer dizer ausência de motivo, nunca um motivo. O que fazer com cada recusa está em Modelos de mensagem.

8. O painel lê quase tudo e escreve quase nada

O que não acontece. Pelo painel você não edita nem apaga modelo, e não cria modelo com cabeçalho, botão, mídia ou rodapé, nem da categoria de autenticação. Escreve o perfil do negócio desde 01/09/2026 (sobre, descrição, e-mail, endereço, dois sites e categoria), mas não envia uma foto nova para o perfil. A foto atual aparece desde 02/09/2026, servida por foto.js. E não vê modelo acima do centésimo.

O que passou a acontecer em 24 de agosto de 2026. Criar um modelo de texto saiu desta lista: hub/canal/[id]/modelo-novo.js faz POST /{waba_id}/message_templates com a autorização do cliente, montando só o componente BODY com o texto e o example das variáveis, e as listas fechadas CATEGORIAS e IDIOMAS do arquivo dizem exatamente o que ele aceita. Depois de submeter, ele relê o modelo na Meta (releModelo()) e devolve confirmado: false quando a releitura não achou: o "ok" de uma escrita não prova que ela aconteceu, e a tela mostra essa diferença em vez de desenhar um modelo que talvez não exista. O teto é de dez criações por hora por conta, com a mesma trilha em evento_webhook que as outras escritas do hub usam. A terceira escrita do painel na Meta é o apontamento do endereço do webhook no número, desde 23 de setembro de 2026, descrito no item 1.1.

Por que. A leitura do perfil devolve apenas tem_foto, e nunca o endereço da imagem, porque o endereço que a Meta manda é assinado e expira em algumas horas: entregue ao navegador, viraria link morto. Some-se a política de segurança da página: o img-src (_middleware.js:67) libera a própria origem, data: e três hosts de Meta e Google, e imagem de host fora dessa lista é descartada pelo navegador sem erro nenhum. Foi por isso que a foto passou meses sem aparecer. Desde 02/09/2026 ela aparece por outro caminho: foto.js busca os bytes no servidor, confere o host contra uma lista fechada e serve com o nosso domínio na frente, então a imagem passa a ser da própria origem e a política aceita. Enviar uma foto nova continua fora, porque exige o caminho de upload da Meta, com outra autorização. A rota que LÊ modelos continua sendo só leitura, com teto de cem por página em modelos.js (a constante LIMITE) e o sinal tem_mais quando a Meta manda o cursor da página seguinte. A analítica por modelo, que traria entregues, leitura e cliques, sai como analitica_por_modelo: false na mesma rota, porque é outra chamada e outra permissão, que este produto nunca fez.

O que você faz no lugar. Escreva o perfil com POST /{phone_number_id}/whatsapp_business_profile, com o seu token ou pelo Gerenciador da Meta. Para modelo com cabeçalho, botão, mídia ou rodapé, e para editar ou apagar, use POST /{waba_id}/message_templates com o seu token, ou o Gerenciador. Acima de cem modelos, pagine pelo cursor after. Os corpos estão em Referência.

9. Dois campos do painel nunca foram lidos

O que não acontece. No cartão Estado na Meta, dentro da aba Detalhes, os campos que dizem se o número pode enviar e qual é a situação do nome verificado nunca trazem valor. Eles aparecem marcados como nunca lidos, e não como um estado do seu número. Não existe aba de saúde no painel: as abas do número são Começar, Detalhes, Perfil, Modelos, Métricas, Atividade e Caixa de entrada, que é a lista fechada ABAS de hub-canal.js.

Por que. health_can_send e name_status não entram em nenhuma das três chamadas de saúde, e a decisão está escrita em _saude-meta.js:28: o primeiro vem de um endpoint que este produto nunca chamou, e o segundo, acrescentado à chamada do número, poria em risco os outros três campos dela, porque um campo inexistente na versão da Graph derruba a resposta inteira com erro 100. As duas colunas existem no banco e continuam vazias, e a tela as exibe assim de propósito, em _canal.js:98 e _canal.js:100, nas linhas Pode enviar e Nome aprovado do cartão (as chaves meta_pode_enviar e meta_status_nome de hub-canal.js).

O que você faz no lugar. Trate a ausência como ausência, e não como um não. Se precisar dessas duas leituras, elas existem na Meta e você pode fazê-las com o seu token. Se der certo, escreva para a Zera: a sua medição vira a nossa.

10. Nada vigia a saúde do seu número sozinho

O que não acontece. Não existe rotina automática lendo a qualidade do seu número, o limite de mensagens ou o estado de revisão da sua conta na Meta. Se a Meta rebaixar a qualidade, cortar o seu limite ou pôr a sua conta em revisão, a Zera não descobre sozinha e não manda aviso.

Por que. As três leituras de saúde só acontecem dentro de saude.js, que é uma rota de painel disparada pelo botão de atualizar. É de lá que sai account_review_status (_saude-meta.js:174), que é o campo do estado de revisão da conta. Nenhuma rotina agendada chama essa rota. E ela tem freios: cinco minutos entre duas leituras do mesmo número (saude.js:58) e vinte leituras por hora por conta (saude.js:59). O produto também só traduz seis códigos de erro da Meta, os que aparecem nas leituras dele, em _saude-meta.js:60 a :62: 190 e 200, 4, 613, 80007 e 100. Qualquer outro vira falha nossa na tela.

O que você faz no lugar. Monte a sua própria vigilância com o seu token, lendo quality_rating, messaging_limit_tier e account_review_status no ritmo que fizer sentido para o seu volume, e guarde o histórico, que a Meta não guarda. As três consultas exatas estão em Referência. E se você vir alguma coisa estranha, escreva para a Zera: quando o problema é de conta, o caminho costuma passar por ela.

11. A credencial não se regenera nem se revoga aqui

O que não acontece. Não existe botão de gerar outra credencial nem de revogar a atual. Também não existe revelar sem barulho: toda exibição avisa o dono da conta por e-mail e fica registrada.

Por que. A decisão está escrita no cabeçalho de credencial.js, e o motivo é honesto: só a Meta revoga esse token, e um botão que promete o que o sistema não cumpre é pior que a ausência dele. Como não dá para rotacionar, também não dá para mostrar uma vez só, então a exibição é repetível e barulhenta. Os limites são três exibições por conta a cada 24 horas corridas, e não por dia do calendário: TETO_POR_DIA vale 3 e JANELA_DO_TETO vale 86400 segundos, e as duas contagens comparam o instante da tentativa contra agora - 86400. Junto com isso, sessão com menos de dez minutos de vida (IDADE_MAXIMA_SESSAO), o que na prática quer dizer entrar de novo, pelo link do e-mail ou com a senha, antes de pedir. O barulho também é código: a exibição só se completa se o aviso ao dono da conta tiver sido aceito pelo servidor de e-mail (a recusa aviso_nao_saiu de decideRevelacao()), e cada exibição concluída fica gravada, com data (SQL_REVELACOES). As quatro constantes estão em functions/api/hub/canal/[id]/credencial.js.

O que você faz no lugar. Guarde o token no seu cofre de segredos na primeira vez, e trate a exibição como recuperação de emergência, não como rotina. O comportamento completo do botão, campo por campo, está em A sua credencial.

12. Trocar de número, ou acrescentar um, não é operação do painel

O que não acontece. Não existe, no painel, um botão para acrescentar um número novo ou para trocar o número de um canal existente. O que existe é reconectar o mesmo canal quando a autorização cai.

Por que. O único lugar do produto que cria um canal é o cadastro, em _lib.js:411, que abre um canal por número comprado no pedido. Nenhuma rota do painel insere canal. Trocar o número de um canal já existente não tem rota nenhuma.

O que você faz no lugar. Escreva para [email protected] antes de mexer. Se você trocar de número por conta própria, o phone_number_id muda e o painel continua apontando para o antigo, o que faz as leituras de saúde e de perfil pararem de casar.

13. Migrar de outro fornecedor não tem botão

O que não acontece. Quem já está em outro fornecedor não faz a migração sozinho pelo painel. A tela mostra a instrução e o caso entra numa fila com gente do outro lado.

Por que. A rota outra_api está declarada em _es.js:151 com self_service: false na linha 155, e sem nenhum passo automático. O comentário ao lado explica: o repositório tinha duas versões escritas sobre esse caminho, e a única execução real concluiu por medição que ele não passa pelo autoatendimento. Além disso, ela depende de terceiro, porque a verificação em duas etapas precisa estar desligada no provedor antigo, e isso a Zera não destrava.

O que você faz no lugar. Fale com a Zera antes de desligar qualquer coisa no fornecedor atual. Migração com a verificação em duas etapas ligada do outro lado trava no meio, e no meio o número não está em lugar nenhum.

14. Se o número entrou por coexistência, o aparelho perde recursos

O que não acontece. Um número que passou pela coexistência continua funcionando no celular, mas o aplicativo deixa de fazer algumas coisas, e isso não volta atrás.

Por que. A rota app_business, em _es.js:80, carrega a lista de limites que a Meta publica para esse caminho, refeita em 11 de agosto de 2026 contra a tabela que ela publica. Os dois mais graves estão marcados como tal: os aparelhos vinculados são desvinculados da conta, e as listas de transmissão são desativadas, sendo que as que existem viram somente leitura. A lista traz ainda grupos que não sincronizam, mensagens temporárias, ver uma vez e localização ao vivo desativados em conversa individual, chamadas de voz e vídeo apenas no aplicativo, catálogo, pedidos e status apenas no aplicativo, e vazão fixa de vinte mensagens por segundo. A lista está em _es.js:123 a :142, e a frase de cada item é a que a tela de conexão escreve (textos.js:326 a :334).

O que você faz no lugar. Confirme por qual rota o seu número entrou antes de prometer qualquer um desses recursos a quem usa o celular. Se a coexistência ainda não aconteceu e algum desses itens for essencial, fale com a Zera antes do clique, e não depois.

15. A Zera não revisa o que você envia

O que não acontece. No plano da API, nenhuma linha do produto lê, filtra, aprova ou recusa o conteúdo das suas mensagens. Não existe moderação, não existe fila de aprovação e não existe alerta de conteúdo.

Por que. É a consequência direta do item 3: as suas mensagens não passam por aqui. O produto não tem nenhuma rota de envio de mensagem. A rota que lista modelos é leitura pura, e a que cria modelo de texto (modelo-novo.js) submete o modelo para a aprovação da Meta. Quem aprova modelo é a Meta, e quem cobra o envio é a Meta, direto de você, o que está escrito em metricas.js:30.

O que você faz no lugar. Leia a política da Meta e desenhe o seu sistema em cima dela, porque a conta que sofre a consequência é a sua. Se a sua leitura desse ponto precisar de tratamento contratual, escreva para [email protected], porque isso é conversa de contrato e não de documentação.

O que a Zera faz quando o contrato termina

Vale estar escrito aqui, porque é uma escrita da Zera dentro da sua conta que não sai de um botão do painel: ela é feita pela operação da Zera, no encerramento. As escritas que saem do painel (o perfil, o modelo novo e o apontamento do webhook) estão no item 3 desta página. No encerramento, a Zera tira a inscrição do aplicativo dela da sua conta de WhatsApp, com DELETE /{waba_id}/subscribed_apps, e depois relê a lista para confirmar que saiu mesmo, em desligar.js:1316 e desligar.js:1330. Se a releitura não confirmar, o passo não é dado como concluído.

A sua conta de WhatsApp, o seu número e a sua conta na Meta continuam sendo seus: eles nunca foram da Zera. O que acontece com o token depois disso depende da Meta, e esta página não afirma o que não mediu.

Se faltar alguma coisa nesta lista

Esta página existe para não deixar você descobrir um buraco sozinho. Se você encontrar um que não está aqui, isso é defeito nosso e a Zera quer saber, porque a próxima pessoa não deveria gastar o mesmo tempo. Escreva para [email protected] com o que você esperava, o que aconteceu e a chamada que você fez.