Conceitos

O vocabulário da plataforma: como um endpoint atende vários clientes, o que é uma WABA, como o cliente conecta a conta dele e por que a identidade do contato é opaca.

Antes de mandar a primeira mensagem, vale entender as ideias que aparecem em toda a API: o modelo multi-tenant, a Conta de canal, os dois ambientes, a WABA, o Embedded Signup sob a aprovação de Tech Provider e a identidade do contato.

Modelo multi-tenant

A BotoZap é feita para quem atende vários clientes de uma vez. A hierarquia é:

account (você, o dev / workspace)
  └─ customer (cada cliente seu; is_self = o seu próprio negócio)
       └─ waba_connection (a WABA do cliente)
            └─ phone_number = channel_account (Conta de canal)
                 └─ contact / conversation / message

A sua account é o topo: é a conta da BotoZap que você administra. Abaixo dela ficam os seus customers, e cada um conecta a própria conta de WhatsApp. Tudo isola por account_id no servidor, então você envia e recebe mensagens em nome de todos os clientes por um endpoint só, sem nunca passar um id de conta na requisição: ele é derivado da sua chave de API.

Cliente self

O cadastro cria um Cliente que representa o próprio negócio da Conta, marcado com is_self: true nas respostas de /api/v1/customers (no máximo um por Conta; Contas antigas podem não ter nenhum marcado). É um Cliente comum: mesma API, mesmas regras. Se você integra só o seu número, ele é o seu único Cliente; se revende, crie um Cliente para cada negócio atendido e use is_self para decidir o que mostrar na sua interface.

Conta de canal

A Conta de canal (channel_account) é o endpoint concreto por onde a conversa acontece. No WhatsApp, cada número é uma Conta de canal. Contatos, conversas, mensagens e mídia pendem dela, e toda leitura desses recursos traz channel e channel_account. Liste as suas em GET /api/v1/channel_accounts; quem só usa WhatsApp pode continuar em GET /api/v1/phone_numbers.

Produção e sandbox

Cada chave de API opera em um de dois ambientes: produção (bz_live_) ou sandbox (bz_sandbox_). A primeira chave sandbox cria, dentro da sua Conta, uma WABA e um número sintéticos ligados ao Cliente mais antigo, o criado no cadastro. Os dados dos dois ambientes não se misturam: a chave sandbox só vê o que é sandbox, nunca chama a Meta e só acessa uma lista restrita de rotas. Detalhes em Sandbox vs. produção.

WABA

WABA é a WhatsApp Business Account, a conta de WhatsApp Business do seu cliente na Meta. Cada WABA tem um ou mais números de telefone e um token de acesso próprio, usado para falar com a Graph API.

Esse token nunca é exposto: fica guardado com segurança no servidor e é resolvido só na hora de chamar a Meta. Você trabalha com a WABA através da API da BotoZap e das suas chaves; o token da conta do cliente não aparece nas respostas nem nos logs.

Embedded Signup e Tech Provider

Para conectar a WABA, o cliente passa pelo Embedded Signup: um fluxo hospedado pela Meta em que ele autoriza (ou cria) a conta de WhatsApp Business dele por um link. No fim, a WABA e o número ficam vinculados à sua plataforma.

Isso funciona porque a BotoZap opera como Tech Provider aprovada pela Meta. A aprovação é nossa, então você não precisa do seu próprio Advanced Access nem de passar pelo App Review da Meta para colocar clientes em produção. Você gera o link, o cliente conecta, e pronto.

A conexão self-service de clientes novos depende de uma aprovação da Meta que está fora do nosso controle direto. Em algum momento ela pode ficar temporariamente indisponível para novas contas, mesmo com o restante da API funcionando normalmente. Se isso acontecer com você, fale com o suporte da BotoZap em suporte@botozap.com.br.

Os detalhes do fluxo estão no artigo Embedded Signup explicado.

Coexistência: contatos e histórico do app

Na coexistência, o número continua no app WhatsApp Business do celular e passa a funcionar também pela API. Logo depois da conexão, a BotoZap pede à Meta, sozinha, duas importações do app: os contatos e o histórico de conversas dos últimos 180 dias. Não há nada a chamar do seu lado.

  • Prazo de 24 horas. A Meta só aceita o pedido nas 24 horas seguintes à conexão, e uma vez por conexão. A BotoZap tenta de novo sozinha se a Meta estiver instável; se o prazo passar sem o pedido aceito, o painel avisa em Canais. Para importar depois disso, é preciso conectar o número de novo.
  • Como o histórico chega. Em lotes, do mais recente (último dia) ao mais antigo (até 180 dias), e pode levar horas. Cada mensagem importada tem source: "history" em GET /api/v1/messages e aparece nas conversas de GET /api/v1/conversations (o last_message também traz source). Como ela chega agora mas é antiga, a ordem padrão de GET /api/v1/messages (chegada ao BotoZap) a mostra como recente; para a ordem cronológica, use sort=event_at.
  • Histórico não é mensagem nova. Nenhuma mensagem importada gera whatsapp.message.received, nem no webhook nem em GET /api/v1/events, e nenhuma aciona agentes, follow-ups ou réguas, nem conta como a última mensagem do contato para os follow-ups. Uma conversa que nasce do histórico já nasce lida no painel. Assim um agente seu não responde a uma conversa de meses atrás.
  • Mídia do histórico. A Meta manda a mídia só das mensagens dos últimos 14 dias antes da conexão, num webhook à parte; a BotoZap baixa e guarda como qualquer mídia recebida. Mensagens de mídia mais antigas ficam na conversa sem o arquivo (tipo unknown), porque a Meta não envia o conteúdo delas.
  • Compartilhamento desligado no app. O histórico só vem se o dono do número deixar ligado o compartilhamento do histórico no app WhatsApp Business. Se estiver desligado, a Meta avisa (erro 2593109), nenhuma conversa antiga é importada e o painel mostra o aviso em Canais. Para importar, é preciso ativar o compartilhamento no app e conectar o número de novo; a BotoZap pede o histórico logo depois da nova conexão, dentro das 24 horas da Meta.
  • Limites da Meta. Mensagens de grupos não vêm.

Identidade e BSUID

A chave que identifica um contato é opaca. Trate-a sempre como um identificador, nunca como um número de telefone.

Com o rollout de WhatsApp Usernames, a Meta desacoplou a identidade do usuário do número. A Cloud API passou a enviar um BSUID (Business-Scoped User ID): um id escopado por empresa, então o mesmo usuário tem BSUIDs diferentes em WABAs diferentes. O formato é o código de país ISO-2, um ponto e até 128 caracteres alfanuméricos, por exemplo BR.1029411383003659.

Na BotoZap, a chave canônica do contato (wa_id) é o BSUID quando ele é conhecido, e os dígitos E.164 quando não é. Ou seja: às vezes o wa_id parece um telefone, às vezes não. Não faça parsing dele como número, não deduza DDI ou DDD a partir dele; use os campos dedicados (telefone, username) quando precisar exibir ou validar.

O contexto completo, incluindo os usernames do WhatsApp, está no artigo WhatsApp Usernames e BSUID.