Primeiros passos

Do zero ao primeiro envio, sem número real e sem custo: gere uma chave de sandbox e teste a API REST ponta a ponta.

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.