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.
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:
Authorization: Bearer whsp_sua_chave_aqui
Alternativamente, use o header X-API-Token:
X-API-Token: whsp_sua_chave_aqui
Formato do token
Todos os tokens seguem o padrão:
whsp_<40 caracteres hexadecimais> Exemplo: whsp_a3f8d2e1c9b74f620a8e5d3c1b9f7e4a2d6c8b5
⚡ Respostas de erro
Todos os erros seguem o mesmo formato JSON:
{
"error": "Descrição do erro"
}
Códigos HTTP
🚦 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.
📨 Enviar mensagem
Envia uma mensagem WhatsApp (texto, mídia ou template) via uma conta conectada.
| Campo | Tipo | Req. | Descrição |
|---|---|---|---|
| account_id | uuid | Sim | UUID da conta WhatsApp conectada no Zivlo |
| to | string | Sim | Número do destinatário com DDI. Apenas dígitos (ex: 5511999998888) |
| type | string | Sim | Tipo: text · image · video · audio · document · template |
| messaging_product | string | Sim | Sempre "whatsapp" |
| text.body | string | Cond. | Corpo da mensagem quando type = "text" |
| image.link | string | Cond. | URL pública da imagem quando type = "image" |
| image.caption | string | Não | Legenda da imagem (opcional) |
| video.link | string | Cond. | URL pública do vídeo quando type = "video" |
| audio.link | string | Cond. | URL pública do áudio quando type = "audio" |
| document.link | string | Cond. | URL pública do documento quando type = "document" |
| document.filename | string | Não | Nome do arquivo a exibir no WhatsApp |
| template.name | string | Cond. | Nome do template aprovado pela Meta (apenas Cloud API) |
| template.language.code | string | Cond. | Ex: "pt_BR" — código de idioma do template |
| template.components | array | Não | Variáveis de preenchimento do template (header, body, buttons) |
Mensagem de texto
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
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)
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" } ] } ] } }'
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" }
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)
// Baileys { "ok": true } // Cloud API { "ok": true, "wa_message_id": "wamid.HBgNNTUxMTk5OTk5ODg4FQIAERgSM..." }
Erros possíveis
account_id must be a valid UUID · "to" must contain only digits · type is requiredInvalid or expired API tokenAccount is bannedAccount not foundBaileys account not connected⚡ 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.
| Campo | Tipo | Req. | Descrição |
|---|---|---|---|
| account_id | uuid | Sim | UUID da conta WhatsApp que enviará as mensagens do fluxo |
| flow_id | uuid | Sim | UUID do fluxo a ser executado. O fluxo deve estar ativo (is_active = true) |
| to | string | Não* | Número do destinatário com DDI. Se omitido, usa variables.phone |
| variables | object | Não | Variáveis iniciais injetadas no fluxo. Mescladas com phone, date e time |
| force | boolean | Não | Se 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ável | Exemplo | Descrição |
|---|---|---|
| {{phone}} | 5511999998888 | Número do destinatário |
| {{date}} | 20/03/2026 | Data atual (formato pt-BR) |
| {{time}} | 14:32:08 | Hora atual (formato pt-BR) |
force: true para cancelar a sessão existente e iniciar uma nova.
Disparar fluxo simples
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
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
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 }'
// 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 }); } });
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)
{
"ok": true,
"session_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
Erros possíveis
account_id must be a valid UUID · flow_id must be a valid UUIDInvalid or expired API tokenAccount not found · Flow not found or not active · Flow does not belong to your tenantPhone already has an active flow session. Pass "force": trueAccount not connected (Baileys desconectado)🗝️ Como gerar um token de API
Tokens de API estão disponíveis para planos Pro e superiores.
Authorization: Bearer whsp_... de todas as chamadas à API.ZIVLO_API_KEY) sempre que possível.
📎 Tipos de mensagem
Compatibilidade por tipo de conta
| Tipo | Baileys | Cloud API | Observação |
|---|---|---|---|
| text | ✓ | ✓ | Suporta emojis e markdown WhatsApp (*bold*, _italic_) |
| image | ✓ | ✓ | JPEG, PNG, WebP. Máx 5 MB (Cloud API) / 16 MB (Baileys) |
| video | ✓ | ✓ | MP4 com codec H.264. Máx 16 MB |
| audio | ✓ | ✓ | MP3, OGG, AAC. Enviado como áudio de voz no Cloud API |
| document | ✓ | ✓ | PDF, DOCX, XLSX, etc. Inclua filename para exibir nome |
| template | ✗ | ✓ | Requer template aprovado pela Meta. Necessário para iniciar conversas |
🧩 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
Olá, {{nome_paciente}}! 👋 Sua consulta com {{medico}} está confirmada: 📅 Data: {{data_consulta}} 🕐 Horário: {{horario}} Responda 1 para confirmar ou 2 para cancelar.
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"
}
}
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.