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 não existe | Onde 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, emperfil-salvar.js. - Criar um modelo de texto, quando você cria na aba Modelos:
POST /{waba_id}/message_templates, emmodelo-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}comwebhook_configuration, seguido da releitura, no motorhub/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.