API e webhooks do BioZap

Para que serve

Com a API, outro sistema lê e cadastra os contatos da sua empresa no BioZap, muda etiquetas e etapas do funil e manda modelos aprovados pelo WhatsApp. Com os webhooks, o BioZap avisa outro sistema na hora em que algo acontece: chegou mensagem, entrou contato novo, o assistente marcou um horário ou passou a conversa para a equipe. É o que o Zapier, o Make e o n8n usam para ligar o BioZap a planilhas, CRMs, e-mail e ao resto das suas ferramentas.

Quem cria as chaves e os webhooks é o dono ou um administrador da empresa, em Configurações, no cartão Integrações. A API funciona com o plano ativo.

Chave e endereço

Todas as chamadas vão para https://biozap.app.br/api/v1, com JSON, e levam a chave no cabeçalho:

Authorization: Bearer bz_SUA_CHAVE
  • A chave aparece uma vez só, quando é criada. O BioZap guarda só uma impressão dela, e não tem como mostrar de novo.
  • Uma chave só manda mensagem pelo WhatsApp se for criada com essa permissão. A Meta cobra cada mensagem no cartão da conta do WhatsApp da empresa.
  • Até 10 chaves ativas por empresa e 120 chamadas por minuto por chave (passou, a resposta é 429, com o cabeçalho Retry-After). Revogue na Configuração a chave que vazar ou que não usar mais.
  • Erros vêm com o código HTTP e um corpo assim: {"erro": {"codigo": "...", "mensagem": "..."}}. 401 é chave errada ou revogada, 402 é empresa sem plano, 404 é o que não existe na sua empresa e 422 é pedido que não dá para cumprir (etiqueta fora do catálogo, modelo não aprovado).

Contatos

Todo contato sai da API neste formato:

{
  "id": "6f1c…",
  "nome": "Maria Souza",
  "telefone": "5521999998888",
  "canal": "whatsapp",
  "usuario": null,
  "etiquetas": ["lead", "site"],
  "etapa": { "id": "a3b9…", "nome": "Novo contato" },
  "observacoes": "Prefere à tarde",
  "origem": "manual",
  "criado_em": "2026-10-26T13:05:12.345+00:00"
}

O telefone só vem nos contatos do WhatsApp; no Instagram, vem o nome de usuário. A origem é conversa (a pessoa escreveu), manual (cadastrado no painel ou pela API) ou importado.

GET /eu

A empresa e a chave. Serve de teste da conexão.

GET /contatos

Os contatos, do mais novo para o mais velho: {"dados": [...], "proximo_cursor": "..."}. Filtros opcionais: etiqueta, etapa_id, telefone, canal (whatsapp ou instagram), limite (até 100) e cursor (o proximo_cursor da página anterior; vem nulo na última).

POST /contatos

Cadastra o contato do WhatsApp pelo telefone, ou atualiza o que já existe (o número com e sem o 9 da frente é a mesma pessoa). Campos: telefone (obrigatório: DDD e número, ou + e o código do país), nome, observacoes, etiquetas (somam às que o contato já tem) e etapa_id. Responde 201 quando cria e 200 quando atualiza.

curl -X POST https://biozap.app.br/api/v1/contatos \
  -H "Authorization: Bearer bz_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"telefone": "21 99999-8888", "nome": "Maria Souza", "etiquetas": ["lead"]}'

GET /contatos/{id}

Um contato.

PATCH /contatos/{id}

Muda só o que vier: nome, observacoes, etiquetas (troca a lista inteira), adicionar_etiquetas, remover_etiquetas e etapa_id (nulo tira do funil).

GET /etiquetas e GET /etapas

O catálogo de etiquetas e as etapas do funil da empresa. As etiquetas usadas na API precisam existir no catálogo (o dono cria no Funil); etiqueta fora dele dá erro 422, e não é criada.

Mensagens pelo WhatsApp

GET /modelos

Os modelos aprovados pela Meta que a API consegue mandar, com o número de variáveis de cada um.

POST /mensagens

Manda um modelo aprovado a um contato: contato_id ou telefone (o contato é cadastrado se ainda não existe; nome opcional), modelo, idioma (opcional) e variaveis, na ordem. A marca {nome} numa variável vira o primeiro nome do contato. Com mais de um número de WhatsApp, numero (opcional) diz por qual sai: o telefone do número da empresa, com DDI e DDD; sem ele, vai pelo principal.

curl -X POST https://biozap.app.br/api/v1/mensagens \
  -H "Authorization: Bearer bz_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{"telefone": "21 99999-8888", "modelo": "boas_vindas", "variaveis": ["{nome}"]}'
  • Só com chave que tem a permissão de enviar, e até 1000 mensagens pela API a cada 24 horas, por empresa.
  • Mande só para quem aceitou receber mensagens da empresa. Modelo de marketing não vai para quem respondeu PARAR, SAIR ou STOP, e nada vai para contato bloqueado.
  • A mensagem aparece na conversa do BioZap, e quem responder é atendido pelo assistente, como em um disparo.

Webhooks

Cadastre um endereço https e escolha os eventos (até 5 webhooks por empresa). O BioZap manda um POST com JSON a cada evento:

  • contato.criado: Contato novo (pela conversa, pelo painel ou pela API).
  • contato.atualizado: Contato mudou (nome, observações, etiquetas ou etapa do funil).
  • mensagem.recebida: Mensagem recebida de um cliente.
  • agendamento.marcado: Horário marcado pelo assistente na agenda.
  • atendimento.transferido: Conversa passada para a equipe.
{
  "id": "0b6e2c1a-…",
  "evento": "mensagem.recebida",
  "criado_em": "2026-10-26T13:07:00.000Z",
  "organizacao": { "slug": "sua-empresa", "nome": "Sua Empresa" },
  "dados": {
    "contato": { "id": "6f1c…", "nome": "Maria Souza", "telefone": "5521999998888", … },
    "conversa": { "id": "9d2e…", "canal": "whatsapp" },
    "mensagem": { "id": "c41a…", "tipo": "texto", "texto": "Oi, vocês abrem sábado?", "criada_em": "…" }
  }
}

Nos eventos de contato vêm também origem (conversa, painel ou api) e, no contato.atualizado, mudou (os campos que mudaram). O agendamento.marcado traz o início em UTC e no horário de Brasília. Contatos importados de arquivo ou da agenda do celular não geram contato.criado.

Entrega e novas tentativas

  • Responda com um código 2xx em até 10 segundos. Fora disso, o BioZap tenta de novo depois de 1, 5 e 15 minutos e de 1, 3, 6 e 12 horas. Depois de 20 falhas seguidas, o webhook é desligado, e você liga de novo na Configuração.
  • O BioZap não segue redirecionamento: cadastre o endereço final.
  • A mesma entrega pode chegar mais de uma vez. Use o id do evento para descartar a repetida.
  • O botão Enviar teste, na Configuração, manda um evento de teste na hora e mostra o que o endereço respondeu.

Assinatura

Cada entrega leva os cabeçalhos X-BioZap-Evento, X-BioZap-Entrega e X-BioZap-Assinatura (t=...,v1=...): o HMAC-SHA256 de <t>.<corpo> com o segredo que aparece uma vez, quando o webhook é criado. Confira assim (Node.js):

import { createHmac, timingSafeEqual } from "node:crypto";

// corpo: o texto CRU do pedido, antes de virar JSON.
function assinaturaConfere(segredo, cabecalho, corpo) {
  const t = Number(/(?:^|,)t=(\d+)/.exec(cabecalho)?.[1]);
  const v1 = /(?:^|,)v1=([0-9a-f]{64})/.exec(cabecalho)?.[1];
  if (!t || !v1 || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const esperado = createHmac("sha256", segredo).update(`${t}.${corpo}`).digest();
  return timingSafeEqual(esperado, Buffer.from(v1, "hex"));
}

Zapier, Make e n8n

  • Para receber eventos: crie o gatilho de webhook da ferramenta (no Zapier, "Webhooks by Zapier", Catch Hook; no Make, Custom webhook; no n8n, o nó Webhook), copie o endereço e cadastre no BioZap.
  • Para agir no BioZap: use o pedido HTTP da ferramenta (no Zapier, Custom Request; no Make, o módulo HTTP; no n8n, o nó HTTP Request) com o endereço da API e o cabeçalho Authorization acima.

Seus dados

O que a API lê e o que os webhooks entregam são dados da sua empresa, e vão para os sistemas que você escolheu. Os eventos ficam guardados no BioZap por até 7 dias, para novas tentativas e conferência. Mais detalhes nos Termos de Uso e na Política de Privacidade. Dúvidas: contato@natariolabs.com.br.