Skip to main content

Campanhas API

🎯 Visão Geral

A API de Campanhas Contínuas (Evergreen) permite adicionar contatos individualmente ou em lote a uma campanha ativa, com controle de agendamento por contato — envio imediato ou em data/hora específica.

Características Principais

  • ✅ Autenticação via API Key: Todas as requisições usam Workspace API Key
  • ✅ Adição de Contatos em Lote: Envie múltiplos contatos em uma única requisição
  • ✅ Agendamento por Contato: Cada contato pode ter seu próprio horário de envio (immediate ou absolute)
  • ✅ Criação Automática de Contatos: Contatos inexistentes são criados automaticamente via identifier
  • ✅ Campos Customizados: Suporte a cf_xxxx top-level e objeto custom_fields
  • ✅ Cancelamento Granular: Cancele o envio de um contato específico sem afetar os demais
  • ✅ Inspeção de Mensagens: Consulte status individual de cada mensagem da campanha

🔐 Autenticação

Todas as requisições requerem autenticação via Workspace API Key no header:

X-API-Key: your_workspace_api_key_here
Content-Type: application/json

Como Obter a API Key

  1. Acesse o painel administrativo do workspace

    Abra o painel administrativo do seu workspace.

  2. Vá em Configurações → API Keys

    Navegue até a seção de API Keys nas configurações.

  3. Gere ou reutilize uma chave

    Gere uma nova chave ou copie/use uma existente.

  4. Mantenha a chave segura

    Não compartilhe a chave e mantenha-a armazenada com segurança.

✅ Validação de Plano/Assinatura

Importante

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 e inspecionar mensagens) podem funcionar mesmo sem a funcionalidade habilitada, permitindo visualizar o estado da campanha. Endpoints que adicionam contatos ou cancelam mensagens requerem a funcionalidade habilitada no plano.

📡 Base URL

https://api.blubash.io/api/v1/campaigns

⚙️ Pré-requisito: Configurar a Campanha na Plataforma

Campanhas Contínuas devem ser criadas e configuradas pelo painel da plataforma antes de usar a API.

Por quê:

  • As regras de canal, template e rate limit são validadas no fluxo do produto.
  • A configuração via plataforma é mais segura para templates e mensagens.
  • Esta API cobre exclusivamente ingestão de audiência e disparo.

Passos recomendados

  1. Crie uma nova campanha com kind = EVERGREEN na plataforma.
  2. Configure o canal, mensagem/template e regras de rate limit.
  3. Salve a campanha e copie o campaignId gerado.

Use esse campaignId em todos os endpoints abaixo.

🚀 Endpoints

Adicionar Contatos à Audiência

POST /api/v1/campaigns/:campaignId/audience

Adiciona um ou mais contatos à campanha e define o agendamento de envio por contato (array items).

Dica

Para adicionar um único contato, envie o array items com apenas um elemento — o endpoint é o mesmo.

Request Body:

{
"default_schedule_timezone": "America/Sao_Paulo",
"items": [
{
"contact_id": "<CONTACT_ID_1>",
"schedule": {
"type": "immediate"
}
},
{
"identifier": "5511999999999",
"name": "João Silva",
"email": "joao@acme.com",
"cf_plano": "pro",
"custom_fields": {
"cf_origem": "api"
},
"schedule": {
"type": "absolute",
"datetime": "2026-03-10T14:30:00.000Z"
}
},
{
"contact_id": "<CONTACT_ID_3>",
"schedule": {
"type": "absolute",
"datetime": "2026-03-11T09:00:00",
"timezone": "America/Sao_Paulo"
}
}
]
}

Campos por item:

CampoTipoObrigatórioDescrição
contact_idstringCondicional¹ID de um contato existente no workspace
identifierstringCondicional¹Identificador do canal (ex: número WhatsApp)
namestringNãoNome do contato (usado na criação)
emailstringNãoEmail do contato (usado na busca e criação)
custom_fieldsobjectNãoCampos customizados como objeto
cf_xxxxunknownNãoCampos customizados como chaves top-level
scheduleobjectNãoConfiguração de agendamento (padrão: immediate)

¹ Pelo menos um entre contact_id ou identifier é obrigatório.

Campo raiz default_schedule_timezone (opcional): Fuso horário IANA aplicado a todos os itens com datetime sem offset/Z que não especificaram schedule.timezone.

Resolução e Criação de Contatos

O sistema resolve o contato na seguinte ordem:

  1. Se contact_id for fornecido, usa o contato existente diretamente.
  2. Se identifier for fornecido, busca o contato pelo identificador do canal (ex: número WhatsApp normalizado).
  3. Se não encontrado e email estiver presente, busca o contato no workspace por email (case-insensitive):
    • Se encontrado e sem identificador para o canal da campanha, vincula o identifier ao contato.
    • Se encontrado mas com identificador diferente para o canal, retorna erro 400 (evita mesclagem silenciosa de identidades).
  4. Se ainda não encontrado, cria um novo contato com name, email e identifier fornecidos.

Campos Customizados

Os campos customizados são aceitos nos dois formatos abaixo e mesclados antes de persistir:

  • Top-level com prefixo cf_: "cf_plano": "pro", "cf_origem": "api"
  • Objeto custom_fields: { "custom_fields": { "cf_plano": "pro" } }

Agendamento por Contato

  • immediate: Enfileira e envia o mais rápido possível.
  • absolute: Agenda o envio para um instante específico, armazenado em UTC.

Regras para absolute:

Formato do datetimeComportamento
Com Z ou offset numérico (+03:00, -0500)Interpretado como instante absoluto; timezone é ignorado
Sem offset (ex: 2026-03-11T09:00:00)Requer schedule.timezone ou default_schedule_timezone para conversão a UTC
Atenção

Se datetime não tiver offset e nenhum fuso horário for fornecido, a requisição retornará erro 400.

Exemplos de schedule:

// Envio imediato
{ "type": "immediate" }

// Instante absoluto com offset embutido (timezone ignorado)
{
"type": "absolute",
"datetime": "2026-03-10T14:30:00.000-03:00"
}

// Horário local sem offset (requer timezone)
{
"type": "absolute",
"datetime": "2026-03-11T09:00:00",
"timezone": "America/Sao_Paulo"
}

// Horário UTC explícito
{
"type": "absolute",
"datetime": "2026-03-10T17:30:00.000Z"
}

Response (sucesso):

{
"items": [
{
"messageId": "<MESSAGE_ID>",
"contactId": "<CONTACT_ID_1>",
"scheduled_at": null,
"scheduled_at_utc": null,
"timezone": null
},
{
"messageId": "<MESSAGE_ID>",
"contactId": "<CONTACT_ID_2>",
"scheduled_at": "2026-03-10T14:30:00.000-03:00",
"scheduled_at_utc": "2026-03-10T17:30:00.000Z",
"timezone": "America/Sao_Paulo"
},
{
"messageId": "<MESSAGE_ID>",
"contactId": "<CONTACT_ID_3>",
"scheduled_at": "2026-03-11T09:00:00.000-03:00",
"scheduled_at_utc": "2026-03-11T12:00:00.000Z",
"timezone": "-03:00"
}
]
}

Campos da resposta por item:

CampoDescrição
messageIdID da mensagem criada (campaign_message.id)
contactIdID do contato resolvido/criado
scheduled_atInstante formatado no fuso IANA enviado (ou no offset do datetime). null se imediato
scheduled_at_utcInstante canônico sempre em UTC (...Z). null se imediato
timezoneNome IANA (ex: America/Sao_Paulo) ou offset (ex: -03:00). null se sem agendamento

Cancelar Envio de uma Mensagem

POST /api/v1/campaigns/:campaignId/messages/:messageId/cancel

Cancela o envio de uma mensagem específica que ainda está na fila.

info

Apenas mensagens com status QUEUED podem ser canceladas. Mensagens já enviadas ou em processamento não são afetadas.

Response (sucesso):

{
"id": "<MESSAGE_ID>",
"status": "CANCELLED"
}

Listar Mensagens da Campanha

GET /api/v1/campaigns/:campaignId/messages?limit=50&offset=0

Retorna uma lista paginada das mensagens da campanha com seus respectivos status.

Parâmetros de Query:

  • limit (opcional): Itens por página (padrão: 50)
  • offset (opcional): Deslocamento para paginação (padrão: 0)

Obter Mensagem por ID

GET /api/v1/campaigns/:campaignId/messages/:messageId

Retorna os detalhes de uma mensagem específica da campanha.


📨 Status de Mensagens

  • PENDING — Aguardando processamento
  • QUEUED — Enfileirada para envio (pode ser cancelada)
  • SENDING — Em processo de envio
  • SENT — Enviada com sucesso
  • FAILED — Falha no envio
  • CANCELLED — Cancelada via API

🔁 Fluxo Recomendado

  1. Configure a campanha Evergreen na plataforma e copie o campaignId.
  2. Adicione contatos via POST /api/v1/campaigns/:id/audience com o array items.
  3. Para envio imediato, use schedule.type = immediate.
  4. Para envio agendado, use schedule.type = absolute com:
    • Um instante ISO com Z ou offset numérico, ou
    • Um datetime sem offset + timezone IANA (ou default_schedule_timezone no body).
  5. Se necessário, cancele um envio específico via POST /api/v1/campaigns/:id/messages/:messageId/cancel.
  6. Inspecione o status das mensagens via GET /api/v1/campaigns/:id/messages.

📝 Exemplos Completos

Adicionar Contato com Envio Imediato

curl -X POST https://api.blubash.io/api/v1/campaigns/{campaignId}/audience \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"identifier": "5511999999999",
"name": "Maria Souza",
"schedule": {
"type": "immediate"
}
}
]
}'

Adicionar Contato com Envio Agendado (horário local)

curl -X POST https://api.blubash.io/api/v1/campaigns/{campaignId}/audience \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"default_schedule_timezone": "America/Sao_Paulo",
"items": [
{
"contact_id": "contact_abc123",
"schedule": {
"type": "absolute",
"datetime": "2026-04-01T10:00:00"
}
}
]
}'

Adição em Lote com Agendamentos Mistos

curl -X POST https://api.blubash.io/api/v1/campaigns/{campaignId}/audience \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"default_schedule_timezone": "America/Sao_Paulo",
"items": [
{
"contact_id": "contact_001",
"schedule": { "type": "immediate" }
},
{
"identifier": "5511888887777",
"name": "Pedro Lima",
"cf_plano": "enterprise",
"schedule": {
"type": "absolute",
"datetime": "2026-04-05T09:00:00",
"timezone": "America/Sao_Paulo"
}
},
{
"contact_id": "contact_003",
"schedule": {
"type": "absolute",
"datetime": "2026-04-06T12:00:00.000Z"
}
}
]
}'

Cancelar um Envio Agendado

curl -X POST https://api.blubash.io/api/v1/campaigns/{campaignId}/messages/{messageId}/cancel \
-H "X-API-Key: your_api_key"

Monitorar Mensagens da Campanha

curl -X GET "https://api.blubash.io/api/v1/campaigns/{campaignId}/messages?limit=50&offset=0" \
-H "X-API-Key: your_api_key"

🚨 Erros Comuns

StatusMensagemCausa
400Each item must provide contact_id or identifierItem sem contact_id nem identifier
400Identifier is invalididentifier vazio ou inválido após normalização
400schedule.timezone (IANA) is required when datetime has no UTC offsetdatetime sem offset e sem timezone
400Campaign is not an evergreen campaigncampaignId pertence a uma campanha não-Evergreen
400Cannot add contacts to cancelled or failed campaignsCampanha com status CANCELLED ou FAILED
400Cannot add contacts while the campaign is paused. Resume the campaign first.Campanha com status PAUSED
400Contact found by email already has a different identifier for this campaign channelConflito de identificador ao buscar contato por email
400Contact does not have a valid channel identifier for this campaign channelContato sem identificador válido para o canal da campanha
403Campaigns feature is not available in your current planRecurso não habilitado na assinatura
404Campaign not foundcampaignId não existe no workspace

🚨 Códigos de Status HTTP

  • 200 — Sucesso
  • 201 — Criado com sucesso
  • 400 — Requisição inválida
  • 401 — Não autorizado (API Key inválida ou não fornecida)
  • 403 — Proibido (Recurso não disponível na assinatura do workspace)
  • 404 — Recurso não encontrado