Zivlo API v1

Documentação da API

A API Zivlo permite enviar mensagens WhatsApp e disparar fluxos de automação programaticamente. Use-a para integrar com seus sistemas, CRMs, plataformas de agendamento e muito mais.

BASE URL https://api.zivlo.com.br
ℹ️ Todos os endpoints aceitam e retornam JSON. Inclua o header Content-Type: application/json em todas as requisições.

🔐 Autenticação

A API usa tokens Bearer para autenticação. Inclua o token no header de cada requisição:

HTTP Header
Authorization: Bearer whsp_sua_chave_aqui

Alternativamente, use o header X-API-Token:

HTTP Header (alternativo)
X-API-Token: whsp_sua_chave_aqui
⚠️ Tokens são exibidos uma única vez no momento da criação. Salve-o em um local seguro — o Zivlo armazena apenas o hash do token e não é possível recuperá-lo.

Formato do token

Todos os tokens seguem o padrão:

Formato
whsp_<40 caracteres hexadecimais>

Exemplo: whsp_a3f8d2e1c9b74f620a8e5d3c1b9f7e4a2d6c8b5

⚡ Respostas de erro

Todos os erros seguem o mesmo formato JSON:

JSON
{
  "error": "Descrição do erro"
}

Códigos HTTP

200Sucesso — operação realizada com êxito
400Bad Request — campo obrigatório ausente ou inválido
401Unauthorized — token ausente, inválido ou expirado
403Forbidden — conta banida ou acesso negado
404Not Found — conta, fluxo ou recurso não encontrado
409Conflict — já existe uma sessão ativa para este número
422Unprocessable — conta Cloud API sem configuração completa
429Too Many Requests — limite de requisições excedido
503Service Unavailable — conta Baileys desconectada
500Internal Server Error — erro inesperado no servidor

🚦 Rate Limit

Os endpoints públicos /v1/* não possuem rate limiting por padrão. O rate limit de 100 req/min aplica-se apenas às rotas internas do painel.

Para ambientes de produção, recomendamos implementar throttling no seu lado para evitar sobrecarga da fila de mensagens.

💡 O envio de mensagens via Baileys é assíncrono — a API confirma o enfileiramento, não a entrega. Use os webhooks do WhatsApp Cloud API para rastrear status de entrega.

📨 Enviar mensagem

Envia uma mensagem WhatsApp (texto, mídia ou template) via uma conta conectada.

POST /v1/messages/send
CampoTipoReq.Descrição
account_iduuidSimUUID da conta WhatsApp conectada no Zivlo
tostringSimNúmero do destinatário com DDI. Apenas dígitos (ex: 5511999998888)
typestringSimTipo: text · image · video · audio · document · template
messaging_productstringSimSempre "whatsapp"
text.bodystringCond.Corpo da mensagem quando type = "text"
image.linkstringCond.URL pública da imagem quando type = "image"
image.captionstringNãoLegenda da imagem (opcional)
video.linkstringCond.URL pública do vídeo quando type = "video"
audio.linkstringCond.URL pública do áudio quando type = "audio"
document.linkstringCond.URL pública do documento quando type = "document"
document.filenamestringNãoNome do arquivo a exibir no WhatsApp
template.namestringCond.Nome do template aprovado pela Meta (apenas Cloud API)
template.language.codestringCond.Ex: "pt_BR" — código de idioma do template
template.componentsarrayNãoVariáveis de preenchimento do template (header, body, buttons)
ℹ️ Envio de templates é suportado apenas em contas WhatsApp Cloud API. Contas Baileys suportam texto e mídia (image, video, audio, document).

Mensagem de texto

bash
curl -X POST https://api.zivlo.com.br/v1/messages/send \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "messaging_product": "whatsapp",
    "to": "5511999998888",
    "type": "text",
    "text": { "body": "Olá! Sua consulta foi confirmada." }
  }'

Imagem com legenda

bash
curl -X POST https://api.zivlo.com.br/v1/messages/send \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "messaging_product": "whatsapp",
    "to": "5511999998888",
    "type": "image",
    "image": {
      "link": "https://exemplo.com/imagem.jpg",
      "caption": "Veja nossa novidade!"
    }
  }'

Template (Cloud API)

bash
curl -X POST https://api.zivlo.com.br/v1/messages/send \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "messaging_product": "whatsapp",
    "to": "5511999998888",
    "type": "template",
    "template": {
      "name": "confirmacao_consulta",
      "language": { "code": "pt_BR" },
      "components": [
        {
          "type": "body",
          "parameters": [
            { "type": "text", "text": "João Silva" },
            { "type": "text", "text": "20/03/2026 às 14h" }
          ]
        }
      ]
    }
  }'
javascript
const response = await fetch('https://api.zivlo.com.br/v1/messages/send', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer whsp_sua_chave',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    account_id: 'uuid-da-conta',
    messaging_product: 'whatsapp',
    to: '5511999998888',
    type: 'text',
    text: { body: 'Olá! Sua consulta foi confirmada.' },
  }),
});

const data = await response.json();
console.log(data); // { ok: true, wa_message_id: "wamid.xxx" }
python
import requests

url = "https://api.zivlo.com.br/v1/messages/send"

headers = {
    "Authorization": "Bearer whsp_sua_chave",
    "Content-Type": "application/json",
}

payload = {
    "account_id": "uuid-da-conta",
    "messaging_product": "whatsapp",
    "to": "5511999998888",
    "type": "text",
    "text": {"body": "Olá! Sua consulta foi confirmada."},
}

response = requests.post(url, json=payload, headers=headers)
print(response.json())  # {'ok': True, 'wa_message_id': 'wamid.xxx'}

Sucesso (200)

JSON
// Baileys
{ "ok": true }

// Cloud API
{
  "ok": true,
  "wa_message_id": "wamid.HBgNNTUxMTk5OTk5ODg4FQIAERgSM..."
}

Erros possíveis

400account_id must be a valid UUID · "to" must contain only digits · type is required
401Invalid or expired API token
403Account is banned
404Account not found
503Baileys account not connected
Testar requisição
200 OK

        

⚡ Disparar fluxo

Inicia uma sessão de automação para um contato, como se ele tivesse enviado a mensagem gatilho. Ideal para campanhas, agendamentos e integrações com outros sistemas.

POST /v1/flows/trigger
CampoTipoReq.Descrição
account_iduuidSimUUID da conta WhatsApp que enviará as mensagens do fluxo
flow_iduuidSimUUID do fluxo a ser executado. O fluxo deve estar ativo (is_active = true)
tostringNão*Número do destinatário com DDI. Se omitido, usa variables.phone
variablesobjectNãoVariáveis iniciais injetadas no fluxo. Mescladas com phone, date e time
forcebooleanNãoSe true, cancela sessão ativa existente e reinicia o fluxo. Padrão: false

* to ou variables.phone são obrigatórios.

Variáveis automáticas

As seguintes variáveis são sempre injetadas na sessão, independente do que você enviar:

VariávelExemploDescrição
{{phone}}5511999998888Número do destinatário
{{date}}20/03/2026Data atual (formato pt-BR)
{{time}}14:32:08Hora atual (formato pt-BR)
⚠️ Se já existir uma sessão ativa para o número, a API retorna 409 Conflict. Use force: true para cancelar a sessão existente e iniciar uma nova.

Disparar fluxo simples

bash
curl -X POST https://api.zivlo.com.br/v1/flows/trigger \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "flow_id": "uuid-do-fluxo",
    "to": "5511999998888"
  }'

Com variáveis personalizadas

bash
curl -X POST https://api.zivlo.com.br/v1/flows/trigger \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "flow_id": "uuid-do-fluxo",
    "to": "5511999998888",
    "variables": {
      "nome_paciente": "João Silva",
      "data_consulta": "20/03/2026",
      "horario": "14h30",
      "medico": "Dr. Carlos"
    }
  }'

Forçar reinício de sessão

bash
curl -X POST https://api.zivlo.com.br/v1/flows/trigger \
  -H "Authorization: Bearer whsp_sua_chave" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "uuid-da-conta",
    "flow_id": "uuid-do-fluxo",
    "to": "5511999998888",
    "force": true
  }'
javascript
// Disparar fluxo com variáveis de agendamento
async function triggerAppointmentFlow(phone, appointment) {
  const response = await fetch('https://api.zivlo.com.br/v1/flows/trigger', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.ZIVLO_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      account_id: process.env.ZIVLO_ACCOUNT_ID,
      flow_id: 'uuid-do-fluxo-consulta',
      to: phone,
      variables: {
        nome_paciente: appointment.patientName,
        data_consulta: appointment.date,
        horario: appointment.time,
        medico: appointment.doctor,
      },
    }),
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(err.error);
  }

  return await response.json();
  // { ok: true, session_id: "uuid-da-sessao" }
}

// Uso com webhook de agendamento
app.post('/webhook/agendamento', async (req, res) => {
  const { phone, ...appointment } = req.body;
  try {
    const result = await triggerAppointmentFlow(phone, appointment);
    res.json({ success: true, session_id: result.session_id });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
});
python
import requests
import os

def trigger_flow(phone: str, flow_id: str, variables: dict = None, force: bool = False):
    """Dispara um fluxo Zivlo para um número de WhatsApp."""
    url = "https://api.zivlo.com.br/v1/flows/trigger"

    headers = {
        "Authorization": f"Bearer {os.environ['ZIVLO_API_KEY']}",
        "Content-Type": "application/json",
    }

    payload = {
        "account_id": os.environ["ZIVLO_ACCOUNT_ID"],
        "flow_id": flow_id,
        "to": phone,
        "force": force,
    }

    if variables:
        payload["variables"] = variables

    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    return response.json()


# Exemplo: Notificar paciente de consulta
result = trigger_flow(
    phone="5511999998888",
    flow_id="uuid-fluxo-consulta",
    variables={
        "nome_paciente": "João Silva",
        "data_consulta": "20/03/2026",
        "horario": "14h30",
    }
)
print(result)  # {'ok': True, 'session_id': 'uuid-da-sessao'}

Sucesso (200)

JSON
{
  "ok": true,
  "session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}

Erros possíveis

400account_id must be a valid UUID · flow_id must be a valid UUID
401Invalid or expired API token
404Account not found · Flow not found or not active · Flow does not belong to your tenant
409Phone already has an active flow session. Pass "force": true
503Account not connected (Baileys desconectado)
Testar requisição
200 OK

        

🗝️ Como gerar um token de API

Tokens de API estão disponíveis para planos Pro e superiores.

1
Acesse Configurações → Tokens de API
No painel do Zivlo, clique no ícone de configurações na barra lateral e selecione a aba Tokens de API.
2
Clique em "Novo token"
Dê um nome descritivo ao token (ex: Integração CRM, Webhook Calendly) e selecione o tempo de expiração: nunca, 30 dias, 90 dias ou 1 ano.
3
Copie o token imediatamente
O token completo é exibido uma única vez. Copie e salve em um gerenciador de senhas ou variável de ambiente. O Zivlo armazena apenas o hash — não é possível recuperar o valor original.
4
Use o token nas requisições
Inclua no header Authorization: Bearer whsp_... de todas as chamadas à API.
5
Revogue quando necessário
Para revogar um token, clique no ícone de lixeira ao lado do token na lista. Isso invalida imediatamente todas as requisições que usam aquele token.
🔒 Nunca exponha tokens de API em código frontend, repositórios públicos ou logs. Use variáveis de ambiente (ZIVLO_API_KEY) sempre que possível.

📎 Tipos de mensagem

Compatibilidade por tipo de conta

TipoBaileysCloud APIObservação
textSuporta emojis e markdown WhatsApp (*bold*, _italic_)
imageJPEG, PNG, WebP. Máx 5 MB (Cloud API) / 16 MB (Baileys)
videoMP4 com codec H.264. Máx 16 MB
audioMP3, OGG, AAC. Enviado como áudio de voz no Cloud API
documentPDF, DOCX, XLSX, etc. Inclua filename para exibir nome
templateRequer template aprovado pela Meta. Necessário para iniciar conversas
💡 Para iniciar uma conversa com um usuário que nunca entrou em contato (janela de 24h), use templates via Cloud API. Para contas Baileys, o número deve ter enviado uma mensagem nas últimas 24h ou estar salvo nos contatos.

🧩 Variáveis de fluxo

Ao disparar um fluxo via API, você pode injetar variáveis que ficam disponíveis em todos os nós usando a sintaxe {{nome_variavel}}.

Exemplo: confirmação de consulta

Nó "Enviar Mensagem" no editor
Olá, {{nome_paciente}}! 👋

Sua consulta com {{medico}} está confirmada:
📅 Data: {{data_consulta}}
🕐 Horário: {{horario}}

Responda 1 para confirmar ou 2 para cancelar.
Chamada de API correspondente
POST /v1/flows/trigger
{
  "account_id": "...",
  "flow_id": "uuid-do-fluxo-consulta",
  "to": "5511999998888",
  "variables": {
    "nome_paciente": "João Silva",
    "medico": "Dr. Carlos Alves",
    "data_consulta": "20/03/2026",
    "horario": "14h30"
  }
}
💡 Todos os valores de variáveis são convertidos para string automaticamente. Datas, números e booleanos são aceitos e convertidos.

Variáveis capturadas por nós "Fazer Pergunta" e "Agente IA" durante a sessão também ficam disponíveis nos nós seguintes usando a mesma sintaxe.