Campanhas API
🎯 Visão Geral
A API pública de Campaigns permite criar, gerenciar e monitorar campanhas de disparo em massa via WhatsApp através de autenticação via API Key.
Características Principais
- ✅ Autenticação via API Key: Todas as requisições usam Workspace API Key
- ✅ Acesso ADMIN: Requisições via API são tratadas como ADMIN (acesso total)
- ✅ Tipos de Mensagem: Suporte a texto simples e templates do WhatsApp
- ✅ Variáveis Dinâmicas: Substituição automática de variáveis (
{{nome}},{{email}}, etc.) - ✅ Agendamento: Envio imediato ou agendado para data/hora específica
- ✅ Filtros Avançados: Seleção de contatos por tags, última interação, conversas abertas e campos customizados
- ✅ Rate Limiting: Controle configurável de mensagens por minuto (1-300)
- ✅ Estatísticas em Tempo Real: Monitoramento completo de progresso e performance
🔐 Autenticação
Todas as requisições requerem autenticação via Workspace API Key no header:
X-API-Key: your_workspace_api_key_here
Como Obter a API Key
-
Acesse o painel administrativo do workspace
Abra o painel administrativo do seu workspace.
-
Vá em Configurações → API Keys
Navegue até a seção de API Keys nas configurações.
-
Gere ou reutilize uma chave
Gere uma nova chave ou copie/uso uma existente.
-
Mantenha a chave segura
Não compartilhe a chave e mantenha-a armazenada com segurança.
✅ Validação de Plano/Assinatura
A funcionalidade de Campaigns deve estar habilitada no plano/assinatura do workspace para usar esta API.
Resposta de Erro (quando a funcionalidade não estiver habilitada):
{
"error": "Forbidden",
"message": "Campaigns feature is not available in your current plan. Please upgrade to access this feature."
}
Status Code: 403 Forbidden
Nota: Endpoints de leitura (listar, obter, estatísticas) podem funcionar mesmo sem a funcionalidade habilitada, permitindo visualizar campanhas existentes. Endpoints que criam, modificam ou executam campanhas requerem a funcionalidade habilitada no plano.
📡 Base URL
https://api.blubash.io/api/v1/campaigns
🚀 Endpoints
Campanhas
Listar Campanhas
GET /api/v1/campaigns
Retorna uma lista paginada de campanhas do workspace.
Parâmetros de Query:
status(opcional): Filtrar por status (DRAFT, SCHEDULED, RUNNING, PAUSED, COMPLETED, CANCELLED)channel_id(opcional): Filtrar por ID do canalpage(opcional): Número da página (padrão: 1)limit(opcional): Itens por página (padrão: 20, máximo: 100)
Criar Campanha
POST /api/v1/campaigns
Cria uma nova campanha de marketing.
Tipos de Campanha:
- TEXT: Mensagem de texto simples com variáveis dinâmicas
- TEMPLATE: Usa um template do WhatsApp aprovado
Campanha de Texto Livre
Para campanhas do tipo TEXT, você define o conteúdo da mensagem diretamente com variáveis dinâmicas.
Exemplo de Request:
{
"name": "Black Friday 2024",
"description": "Promoção de Black Friday",
"message_type": "TEXT",
"content": {
"type": "text",
"text": {
"body": "Olá {{nome}}! Aproveite nossa promoção de Black Friday com 50% de desconto!"
}
},
"channel_id": "channel_123",
"filters": {
"tag_ids": ["tag_vip", "tag_clientes"],
"has_open_conversation": false
},
"rate_limit_per_minute": 60
}
Variáveis Dinâmicas Disponíveis:
{{nome}}- Nome do contato{{email}}- Email do contato{{telefone}}- Telefone do contato- Campos customizados:
{{campo_customizado}}(use akeydo campo customizado)
Campanha com Template
Para campanhas do tipo TEMPLATE, você deve usar um template do WhatsApp aprovado. Os templates permitem envio para contatos que não iniciaram conversa (conforme política do WhatsApp).
Passo a Passo:
-
Listar templates disponíveis
GET /api/v1/campaigns/templates?channel_id={channel_id} -
Obter o template_id
Selecione o
template_iddo template que deseja usar. -
Mapear variáveis do template
Mapeie as variáveis do template para campos do contato usando
template_variable_mappingno payload.
Exemplo de Request:
{
"name": "Lembrete de Pagamento",
"description": "Lembrete mensal de pagamento via template",
"message_type": "TEMPLATE",
"template_id": "template_123",
"channel_id": "channel_123",
"filters": {
"tag_ids": ["tag_clientes_ativos"]
},
"metadata": {
"template_variable_mapping": {
"{{1}}": "nome",
"{{2}}": "valor_pagamento",
"{{3}}": "data_vencimento"
}
},
"rate_limit_per_minute": 60
}
Como funciona o mapeamento de variáveis:
O template_variable_mapping mapeia as variáveis do template (como {{1}}, {{2}}, etc.) para campos do contato:
- Campos padrão do contato:
"nome"→ Nome do contato"email"→ Email do contato"telefone"ou"phone"→ Telefone do contato
- Campos customizados:
- Use a
keydo campo customizado (obtida viaGET /api/v1/campaigns/custom-fields) - Exemplo:
"valor_pagamento"→ Valor do campo customizado com keyvalor_pagamento
- Use a
Exemplo Completo:
Suponha que você tenha um template do WhatsApp com o seguinte conteúdo:
Olá {{1}}, seu pagamento de R$ {{2}} vence em {{3}}.
Para mapear:
{{1}}→ Nome do contato{{2}}→ Campo customizado "valor_pagamento"{{3}}→ Campo customizado "data_vencimento"
O request seria:
{
"name": "Lembrete Pagamento",
"message_type": "TEMPLATE",
"template_id": "template_123",
"channel_id": "channel_123",
"metadata": {
"template_variable_mapping": {
"{{1}}": "nome",
"{{2}}": "valor_pagamento",
"{{3}}": "data_vencimento"
}
},
"filters": {
"tag_ids": ["tag_pendentes"]
}
}
- O template deve estar aprovado pelo WhatsApp
- O número de variáveis no
template_variable_mappingdeve corresponder às variáveis do template - As variáveis do template são numeradas sequencialmente (
{{1}},{{2}},{{3}}, etc.)
Obter Campanha por ID
GET /api/v1/campaigns/{id}
Retorna os detalhes de uma campanha específica.
Atualizar Campanha
PUT /api/v1/campaigns/{id}
Atualiza uma campanha existente. Apenas campanhas com status DRAFT podem ser atualizadas.
Deletar Campanha
DELETE /api/v1/campaigns/{id}
Deleta uma campanha. Apenas campanhas com status DRAFT ou COMPLETED podem ser deletadas.
Iniciar Campanha
POST /api/v1/campaigns/{id}/start
Inicia uma campanha imediatamente ou agenda para execução futura.
Pausar Campanha
POST /api/v1/campaigns/{id}/pause
Pausa uma campanha em execução. Apenas campanhas com status RUNNING podem ser pausadas.
Retomar Campanha
POST /api/v1/campaigns/{id}/resume
Retoma uma campanha pausada. Apenas campanhas com status PAUSED podem ser retomadas.
Cancelar Campanha
POST /api/v1/campaigns/{id}/cancel
Cancela uma campanha. Pode ser aplicado a campanhas em qualquer status exceto COMPLETED e CANCELLED.
Obter Estatísticas
GET /api/v1/campaigns/{id}/stats
Retorna estatísticas detalhadas da campanha:
- Total de contatos
- Mensagens enviadas/pendentes/falhadas
- Taxa de sucesso
Obter Mensagens
GET /api/v1/campaigns/{id}/messages
Retorna uma lista paginada de mensagens da campanha.
Parâmetros de Query:
status(opcional): Filtrar por status (PENDING, SENT, DELIVERED, READ, FAILED)page(opcional): Número da página (padrão: 1)limit(opcional): Itens por página (padrão: 20, máximo: 100)
Recursos Disponíveis
Listar Tags
GET /api/v1/campaigns/tags
Retorna todas as tags disponíveis no workspace que podem ser usadas para filtrar contatos.
Listar Canais
GET /api/v1/campaigns/channels
Retorna todos os canais WhatsApp ativos disponíveis no workspace.
Listar Templates
GET /api/v1/campaigns/templates?channel_id={channel_id}
Retorna todos os templates e quick replies disponíveis no workspace.
Parâmetros de Query:
channel_id(opcional): Filtrar templates por ID do canal
Listar Campos Customizados
GET /api/v1/campaigns/custom-fields
Retorna todos os campos customizados do tipo CONTACT disponíveis no workspace. Use o campo key da resposta para referenciar campos customizados nos filtros de campanha.
Exemplo de Response:
[
{
"id": "field_123",
"name": "Cidade",
"key": "city",
"type": "TEXT",
"is_required": false,
"is_visible": true,
"description": "Cidade do contato"
},
{
"id": "field_456",
"name": "Idade",
"key": "age",
"type": "NUMBER",
"is_required": false,
"is_visible": true
}
]
Uso nos Filtros:
Use o campo key nos filtros de campanha:
{
"filters": {
"field_filters": [
{
"field": "city",
"operator": "contains",
"value": "São",
"is_custom_field": true
}
]
}
}
Preview
Preview de Campanha
POST /api/v1/campaigns/preview
Calcula quantos contatos correspondem aos filtros fornecidos antes de criar a campanha.
Exemplo de Request:
{
"filters": {
"tag_ids": ["tag_vip"],
"has_open_conversation": false
},
"channel_id": "channel_123",
"includeDetails": true
}
📊 Status de Campanhas
- DRAFT - Rascunho, não iniciada
- SCHEDULED - Agendada para execução futura
- RUNNING - Em execução
- PAUSED - Pausada temporariamente
- COMPLETED - Concluída com sucesso
- CANCELLED - Cancelada
📨 Status de Mensagens
- PENDING - Aguardando envio
- SENT - Enviada com sucesso
- DELIVERED - Entregue ao destinatário
- READ - Lida pelo destinatário
- FAILED - Falha no envio
🔧 Filtros de Contatos
Os filtros permitem selecionar quais contatos receberão a campanha:
Tags
{
"filters": {
"tag_ids": ["tag_vip", "tag_clientes"]
}
}
Última Interação
{
"filters": {
"last_interaction": {
"from": "2024-01-01T00:00:00Z",
"to": "2024-12-31T23:59:59Z"
}
}
}
Conversas Abertas
{
"filters": {
"has_open_conversation": false
}
}
Campos Customizados
Os filtros de campos customizados suportam dois formatos:
Formato Simples (Legado) - Igualdade Exata
{
"filters": {
"custom_fields": {
"city": "São Paulo",
"age": 25
}
}
}
Este formato apenas verifica igualdade exata. Útil para filtros simples.
Formato Avançado (Recomendado) - Com Operadores
{
"filters": {
"field_filters": [
{
"field": "city",
"operator": "contains",
"value": "São",
"is_custom_field": true
},
{
"field": "age",
"operator": "equals",
"value": 25,
"is_custom_field": true
},
{
"field": "name",
"operator": "starts_with",
"value": "João",
"is_custom_field": false
}
]
}
}
Operadores Disponíveis:
| Operador | Descrição | Requer value | Exemplo |
|---|---|---|---|
equals | Igual a (case-insensitive para strings) | ✅ Sim | { "operator": "equals", "value": "São Paulo" } |
not_equals | Diferente de (case-insensitive para strings) | ✅ Sim | { "operator": "not_equals", "value": "Rio" } |
contains | Contém o valor (case-insensitive) | ✅ Sim | { "operator": "contains", "value": "São" } |
not_contains | Não contém o valor (case-insensitive) | ✅ Sim | { "operator": "not_contains", "value": "Teste" } |
starts_with | Começa com (case-insensitive) | ✅ Sim | { "operator": "starts_with", "value": "João" } |
ends_with | Termina com (case-insensitive) | ✅ Sim | { "operator": "ends_with", "value": "Silva" } |
is_empty | Campo vazio ou não existe | ❌ Não | { "operator": "is_empty" } |
is_not_empty | Campo preenchido | ❌ Não | { "operator": "is_not_empty" } |
Campos Suportados:
- Campos padrão (defina
is_custom_field: false):name- Nome do contatoemail- Email do contatophone- Telefone do contato
- Campos customizados (defina
is_custom_field: true):- Qualquer campo customizado criado no workspace (use a
keydo campo)
- Qualquer campo customizado criado no workspace (use a
Exemplos de Uso:
// Contatos com cidade que contém "São"
{
"field_filters": [
{
"field": "city",
"operator": "contains",
"value": "São",
"is_custom_field": true
}
]
}
// Contatos com idade maior que 18 (usando not_equals para valores menores)
{
"field_filters": [
{
"field": "age",
"operator": "not_equals",
"value": 17,
"is_custom_field": true
}
]
}
// Contatos com nome que começa com "João"
{
"field_filters": [
{
"field": "name",
"operator": "starts_with",
"value": "João",
"is_custom_field": false
}
]
}
// Contatos com campo customizado preenchido
{
"field_filters": [
{
"field": "preferred_language",
"operator": "is_not_empty",
"is_custom_field": true
}
]
}
// Múltiplos filtros (AND lógico)
{
"field_filters": [
{
"field": "city",
"operator": "contains",
"value": "São",
"is_custom_field": true
},
{
"field": "age",
"operator": "equals",
"value": 25,
"is_custom_field": true
}
]
}
Combinação de Filtros
{
"filters": {
"tag_ids": ["tag_vip"],
"last_interaction": {
"from": "2024-01-01T00:00:00Z"
},
"has_open_conversation": false,
"custom_fields": {
"city": "São Paulo"
}
}
}
💬 Variáveis Dinâmicas
Em campanhas do tipo TEXT, você pode usar variáveis dinâmicas que serão substituídas pelos dados do contato:
{{nome}}- Nome do contato{{email}}- Email do contato{{telefone}}- Telefone do contato- Campos customizados:
{{campo_customizado}}
Exemplo:
Olá {{nome}}! Seu email é {{email}} e você está em {{cidade}}.
📈 Rate Limiting
- Padrão: 300 mensagens por minuto
- Configurável: Entre 1-300 mensagens por minuto
- Aplicado por campanha: Cada campanha tem seu próprio rate limit
📝 Exemplos Completos
Criar e Iniciar Campanha de Texto
-
Criar campanha
curl -X POST https://api.example.com/api/v1/campaigns \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Promoção Black Friday",
"message_type": "TEXT",
"content": {
"type": "text",
"text": {
"body": "Olá {{nome}}! Aproveite 50% de desconto na Black Friday!"
}
},
"channel_id": "channel_123",
"filters": {
"tag_ids": ["tag_vip"]
},
"rate_limit_per_minute": 60
}' -
Iniciar campanha
(use o ID retornado)
curl -X POST https://api.example.com/api/v1/campaigns/{campaign_id}/start \
-H "X-API-Key: your_api_key"
Criar Campanha Agendada
curl -X POST https://api.example.com/api/v1/campaigns \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Promoção Natal",
"message_type": "TEXT",
"content": {
"type": "text",
"text": {
"body": "Feliz Natal {{nome}}! Aproveite nossos descontos especiais!"
}
},
"channel_id": "channel_123",
"scheduled_at": "2024-12-25T08:00:00Z",
"rate_limit_per_minute": 120
}'
Preview Antes de Criar
curl -X POST https://api.example.com/api/v1/campaigns/preview \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"tag_ids": ["tag_vip"],
"has_open_conversation": false
},
"channel_id": "channel_123",
"includeDetails": true
}'
Monitorar Estatísticas
curl -X GET https://api.example.com/api/v1/campaigns/{campaign_id}/stats \
-H "X-API-Key: your_api_key"
🚨 Códigos de Status HTTP
200- Sucesso201- Criado com sucesso204- Sem conteúdo (deletado com sucesso)400- Requisição inválida401- Não autorizado (API Key inválida ou não fornecida)403- Não autorizado (Recurso não disponível na assinatura do workspace)404- Recurso não encontrado