Este guia usa uma chave de sandbox (bz_sandbox_): ela não chama a Meta e não consome quota. Qualquer destino é aceito e o envio é simulado; os números mágicos abaixo escolhem o que acontece depois. É o caminho mais rápido para conhecer a API antes de conectar um número de verdade. O caminho principal desta e de todas as outras páginas de guia é a API REST (curl/TypeScript/JavaScript); veja a nota sobre o SDK Node ao final.
Gere uma chave de sandbox
No painel da BotoZap, abra Configurações › Desenvolvedores › Chaves de API (só Administrador cria chaves), gere uma chave nova, escolha o ambiente Sandbox e marque os escopos messages:send e messages:read. Guarde o valor num lugar seguro: ele é mostrado uma vez só. Exporte a chave no seu ambiente:
export BOTOZAP_KEY="bz_sandbox_..."A conta é derivada da chave, então você nunca passa um id de conta. O isolamento multi-tenant é garantido no servidor. Detalhes em Autenticação.
Envie a primeira mensagem
Faça um POST para /api/v1/messages usando o número mágico +5500000000001. Ele simula todo o ciclo de vida (entregue, depois lida) e sempre tem a janela de atendimento aberta:
Enviar uma mensagem de texto (sandbox)
Testa o envio ponta a ponta sem credenciais Meta e sem custo, usando o número mágico de happy path do sandbox.
curl https://botozap.com.br/api/v1/messages \
-X POST \
-H "X-API-Key: $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+5500000000001",
"type": "text",
"text": {
"body": "Oi! 👋 Tudo bem?"
}
}'Resposta 201
{
"id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
"wamid": "wamid.HBgNNTU5MTk5OTk5OTk5FQIAERgSM0FCQzFEMkUzRjRBNUI2QzdEAA==",
"to": "5500000000001",
"sent_to": "5500000000001",
"status": "sent",
"sandbox": true
}Chave sandbox (`bz_sandbox_`) nunca chama a Meta e não consome cota. A origem é sempre o número sintético da conta; o destino pode ser qualquer telefone, e a entrega é simulada. Os números mágicos escolhem o cenário.
`to` é o destinatário que você endereçou, só com dígitos; `sent_to` é o endereço usado no envio. No sandbox os dois são iguais.
O número mágico de happy path mantém a janela de 24h sempre aberta. Para outros destinos, texto fora da janela é 422 `outside_window`, como em produção.
Depois do 201, o BotoZap simula o ciclo de vida (delivered → read no happy path) e dispara seu webhook assinado, como em produção.
Envie um template
No sandbox qualquer nome de template é aceito no envio (a Meta não é chamada para validar o catálogo). Em produção, o template precisa existir e estar APPROVED na WABA. Para submeter um novo, use POST /api/v1/templates com waba_connection_id ou phone_number_id da listagem de números. Com a chave sandbox, o template é criado já APPROVED num catálogo sintético, sem passar pela Meta; em produção ele volta PENDING até a Meta aprovar.
Enviar um template (sandbox)
No sandbox, qualquer nome de template é aceito — a Meta não é chamada, então não há catálogo para validar contra.
curl https://botozap.com.br/api/v1/messages \
-X POST \
-H "X-API-Key: $BOTOZAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+5500000000001",
"type": "template",
"template": {
"name": "boas_vindas",
"language": {
"code": "pt_BR"
}
}
}'Resposta 201
{
"id": "5b0a9d0e-6e1a-4f3b-8c2d-1a9f6e0b7c11",
"wamid": "wamid.HBgNNTU5MTk5OTk5OTk5FQIAERgSM0FCQzFEMkUzRjRBNUI2QzdEAA==",
"to": "5500000000001",
"sent_to": "5500000000001",
"status": "sent",
"warnings": [
{
"code": "consent_unspecified",
"message": "Consentimento de marketing não informado para este contato."
}
],
"sandbox": true
}Como no texto, o destino pode ser qualquer telefone: o sandbox simula a entrega sem chamar a Meta. Template não depende da janela de 24h.
Template fora do catálogo da conta conta como MARKETING para a guarda de consentimento. Sem Consentimento de marketing registrado para o contato, o envio segue e a resposta traz `warnings` com `consent_unspecified`.
Em produção (chave live), o template precisa existir e estar APPROVED na WABA; quem recusa um nome desconhecido é a Meta.
Liste suas mensagens
Listar mensagens
Lista as mensagens da conta, mais recentes primeiro, paginado por cursor. `sort=created_at` (padrão) ordena pela chegada ao BotoZap; `sort=event_at`, pela data real da mensagem.
curl https://botozap.com.br/api/v1/messages?limit=2 \
-H "X-API-Key: $BOTOZAP_KEY"Resposta 200
{
"data": [],
"paging": {
"cursors": {
"before": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa",
"after": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa"
},
"next": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa",
"previous": "MjAyNi0wNy0xNFQxMjowMDowMC4wMDBa"
}
}`sort=created_at` (padrão) é a ordem de chegada ao BotoZap: use-a para sincronizar com `before`, porque nenhuma mensagem entra atrás de um cursor já lido. Nessa ordem, o histórico importado do app na coexistência (`source: "history"`) aparece como recente, porque chegou agora.
`sort=event_at` ordena pela data real da mensagem (`event_at`) — o jeito de mostrar uma conversa em ordem cronológica com o histórico importado no lugar certo. O cursor carrega o valor da ordem que o gerou (em `event_at`, junto com o `id`, para mensagens do mesmo segundo não se perderem entre páginas): use-o com o mesmo `sort`. Outro valor em `sort` responde 422 `invalid_request`.
Próximos passos
- Enviar mensagens: a janela de 24h, telefone vs. BSUID e todos os cenários do sandbox.
- Webhooks: receba eventos de mensagem e status de entrega, inclusive os que o sandbox simula.
- Confiabilidade e entrega: o que a API garante (e o que não garante) sobre duplicatas, ordem e retries.
- Quando estiver pronto para um número real, troque a chave por uma
bz_live_. O mesmo código funciona, só o ambiente muda.
Prefere Node.js? O @botozap/sdk já está publicado no npm (ver SDK Node). Ele é um envelope tipado sobre a mesma API REST usada nos exemplos acima.
