Skip to main content
Campanhas pela API permitem que integrações externas disparem mensagens em massa com a mesma flexibilidade do painel: escolher plataforma, modelo de mensagem, cadência de envio e público-alvo filtrado por tags, funil, canal de entrada, datas e dezenas de outros critérios. Este guia cobre o fluxo completo, do zero ao acompanhamento da execução. Para autenticação e chaves, veja a Introdução à API. Para o conceito de disparo no produto, veja Disparos e Modelos de mensagem.

Pré-requisitos

Base URL: gateway.crmspark.com.br (prefixo /v1).

Como funciona

Uma campanha passa por estados previsíveis: Por que criar e iniciar em duas etapas? No painel, ao clicar em “Iniciar”, o Spark abre o diálogo de variáveis do modelo antes de disparar. A API reproduz esse comportamento:
  1. POST /v1/campaigns — salva a campanha em draft com template, plataforma, cadência e filtros.
  2. POST /v1/campaigns/{id}/start — valida variáveis manuais, resolve o público e enfileira os envios.
Isso permite inspecionar a configuração, estimar o público com audience-preview e só então confirmar o disparo com as variáveis corretas.

Visão geral dos endpoints

A referência interativa ao lado (OpenAPI) documenta cada campo, código de erro e exemplo de request/response.

Tutorial passo a passo

1

Escolher o modelo de mensagem

Liste os templates e anote o id do modelo desejado:
Resposta resumida:
O campo isOfficial indica se o modelo passou pela aprovação da Meta (WhatsApp Business / Instagram). Modelos oficiais só podem ser usados com platform: "whatsapp" ou "instagram".
2

Consultar variáveis do modelo

Antes de iniciar, veja quais variáveis manuais você precisará preencher:
Cada entrada em commonVariables corresponde a uma variável manual do modelo. Variáveis automáticas (nome do chat, contato, etc.) não aparecem aqui — o Spark resolve por destinatário no envio.
3

Montar filtros de público-alvo

Consulte o catálogo de campos:
Estime o tamanho do público antes de criar a campanha:
Se estimatedCount for 0, revise os filtros antes de prosseguir.
4

Criar a campanha (rascunho)

Guarde o campaignId — você usará nas próximas chamadas.
5

Iniciar o disparo

Envie commonVariables se o template tiver variáveis manuais:
Se o modelo não tiver variáveis manuais, envie {} ou omita o body.
6

Acompanhar progresso

Faça polling até status ser completed, failed ou canceled:
Intervalo sugerido: a cada 10–30 segundos. progress vai de 0 a 100 com base em sentCount + failedCount sobre targetCount.

Plataforma e compatibilidade com templates

O campo platform no body da campanha define o canal de envio e impacta cadência, limites e compatibilidade com templates:
O campo platform da campanha não restringe automaticamente quais chats entram no público. Para enviar só para chats de um canal, inclua explicitamente um filtro chat.platform (veja Filtros de público-alvo).
Se você escolher um template oficial (isOfficial: true) com platform: "whatsapp_lite", a API retorna CAMPAIGN_TEMPLATE_PLATFORM_MISMATCH.

Cadência

cadence é um número inteiro ≥ 1 que representa quantas mensagens por minuto a campanha tenta enviar. Exemplo: "cadence": 10 → até 10 mensagens por minuto, espaçadas uniformemente. Cada plataforma tem limites internos de throughput. Valores muito altos não aceleram além do teto da plataforma — o Spark respeita os limites para evitar bloqueios nos canais.
Para a primeira integração, use cadência baixa (5–10) e aumente gradualmente conforme observar taxa de sucesso e respostas dos destinatários.

Variáveis do modelo

Modelos podem ter trechos dinâmicos ({{1}}, {{2}}, …). Na API existem dois comportamentos:

Variáveis manuais (commonVariables)

Valores que você informa uma vez no start e que valem iguais para todos os destinatários da execução.
Como saber o que enviar: chame GET /v1/message-templates/{id} e leia o array commonVariables. Cada item tem key (ex.: var1), label (nome amigável) e required. Se faltar alguma variável manual obrigatória, a API responde com CAMPAIGN_MISSING_COMMON_VARIABLES.

Variáveis automáticas (dados do chat)

Configuradas no painel como Automático — dados do chat (nome, contato, aniversário, campo personalizado). O Spark preenche por destinatário no momento do envio. Não envie variáveis automáticas no body — elas não aparecem em commonVariables e são resolvidas internamente.
Se um chat não tiver nome ou campo personalizado preenchido, a variável automática correspondente pode sair em branco na mensagem. Antes de disparar em massa, confira a qualidade dos dados ou use filtros para excluir chats incompletos.

Exemplo combinado

Modelo: "Olá {{1}}, aproveite {{2}} com desconto exclusivo!"
  • {{1}} → automática (nome do chat) — não enviar
  • {{2}} → manual (nome da promoção) — enviar como "var2": "Black Friday"
Body do start:
Cada destinatário recebe: "Olá Maria, aproveite Black Friday com desconto exclusivo!" (Maria vem do chat; Black Friday é fixo). Para detalhes sobre tipos de variável e configuração no painel, veja Modelos de mensagem.

Filtros de público-alvo

Filtros definem quais chats recebem a campanha. A estrutura é a mesma usada no painel de disparos.

Estrutura JSON

Regras de combinação

Exemplo com OR dentro de um grupo: “Chats com tag VIP ou tag Premium, desde que sejam WhatsApp”:
Grupo 1 (VIP ou Premium) AND Grupo 2 (WhatsApp).

Campos disponíveis

Consulte sempre GET /v1/campaigns/filters/schema para a lista atualizada. Referência completa: IDs semânticos (tag_…, entrypoint_…, funnel_step_…) são os mesmos retornados pela API interna e visíveis no painel.

Operadores por tipo

Operadores exists / not-exists não exigem value. Operadores between / not-between usam value e value2.

Exemplos práticos de filtros

Apenas WhatsApp Business:
Chats com tag “Cliente ativo” (has-all garante que a tag está presente):
Chats sem nenhuma das tags “Inativo” ou “Bloqueado”:
Última mensagem nos últimos 7 dias:
Aniversariantes em maio (intervalo de datas):
Chats em etapa específica do funil:
Chats que ainda não foram respondidos:
Canal de entrada específico:
Antes de iniciar uma campanha grande, chame POST /v1/campaigns/audience-preview com os mesmos filtros. Isso evita surpresas com público vazio ou maior que o esperado.

Estimar público (audience-preview)

Calcula quantos chats corresponderiam aos filtros sem criar campanha e sem enviar mensagens.
Resposta:
O endpoint aceita os mesmos filtros de POST /v1/campaigns. Omitir filters conta todos os chats da organização.

Status e monitoramento

Status da campanha

Detalhe com execuções

GET /v1/campaigns/{id} retorna a campanha e o histórico de execuções:

Progresso de uma execução

GET /v1/campaigns/{id}/executions/{executionId}:

Cancelar

Resposta: 204 No Content. Interrompe a execução em andamento; envios já enfileirados podem ainda ser processados conforme o estado da fila.

Exemplo completo (TypeScript com SDK)

Veja SDK TypeScript para instalação e configuração.

Erros comuns

Todas as respostas de erro seguem { statusCode, code, message }. Trate pelo campo code, não pela mensagem.

Limite de tamanho da campanha

O Spark valida se o público cabe no volume máximo estimado para 24 horas na plataforma escolhida. Se audience-preview retornar um número alto, considere segmentar (por tag, funil ou data) em múltiplas campanhas sequenciais.

Boas práticas

  1. Segmente antes de escalar — use tags, funil e datas para públicos menores e mais relevantes.
  2. Sempre faça previewaudience-preview evita disparos para 0 contatos ou bases enormes acidentais.
  3. Valide variáveis — consulte GET /v1/message-templates/{id} antes do start; erros de variável só aparecem na hora de iniciar.
  4. Respeite janelas de canal — modelos internos no WhatsApp/Instagram só funcionam dentro da janela de resposta; fora dela, use modelos oficiais.
  5. Monitore failedCount — falhas podem indicar chats sem janela, números inválidos ou problemas de template.
  6. Cadência conservadora — comece com 5–10 msg/min e ajuste conforme resultados.
  7. Nomes descritivosname deve ser único e identificável ("Promoção maio VIP", não "Campanha 1").
  8. Idempotência no start — se a requisição de start falhar por timeout de rede, consulte GET /v1/campaigns/{id} antes de tentar novamente para evitar duplicar execuções.

Leitura adicional