Disparador em Massa

Envio em massa via WhatsApp/API/SMS com origem por CSV, etiquetas de contato ou estágio do Kanban. Inclui controles de cadência (janela de horário, rotação de inbox, delays, spintax), follow-up e blacklist por conta. As mensagens reusam o fluxo nativo de conversa do NooviChat.

Licença e respostas

O Disparador está disponível em toda licença NooviChat válida. O acesso também depende das permissões do usuário e do estado operacional da conta. As respostas de listagem são arrays puros e as de detalhe são objetos puros (sem wrapper data). A listagem retorna um resumo (id, nome, tipo, status e contadores); os campos completos de configuração (source_config, message_payload, follow_up_message, inbox_weights) vêm apenas no detalhe (GET /broadcasts/{id}).

Listar Disparos

GET/api/v1/accounts/{account_id}/broadcasts

Lista os disparos da conta, ordenados por mais recentes.

Query

NomeTipoObrigatorioDescricao
statusstringNaopending | running | paused | completed | cancelled | failed
qstringNaoBusca por nome (ILIKE)
limitintegerNaoTamanho da página (max 100, padrão 50)
offsetintegerNaoDeslocamento para paginação
200Array de disparos
json
[
  {
    "id": 42,
    "name": "Promocao de Junho",
    "source_type": "tags",
    "message_type": "custom",
    "status": "running",
    "total_count": 100,
    "sent_count": 87,
    "failed_count": 2,
    "reply_count": 15,
    "delivery_rate": 87.0,
    "created_at": "2026-06-02T11:58:00Z"
  }
]

Criar Disparo

POST/api/v1/accounts/{account_id}/broadcasts

Cria um disparo e enfileira a resolução dos contatos.

Origem dos contatos (source_type / source_config)

csv{ "csv_rows": [{ "telefone": "...", "nome": "..." }] }; tags{ "tag_ids": [1, 2] } (etiquetas de contato); kanban{ "funnel_id": 1, "stage_ids": ["755_lead"] } (estágios do funil — o disparo reusa a conversa já vinculada a cada card).

No csv, a coluna de telefone aceita os apelidos telefone/phone/celular/whatsapp/numero/number/tel e a de nome nome/name/contato/cliente (case-insensitive). Colunas extras viram variáveis do template ({{coluna}}).

Resposta

Em caso de sucesso a criação retorna HTTP 200 (não 201) com o objeto do disparo (sem wrapper data). Variáveis suportadas na mensagem: {{nome}}, {{telefone}} e qualquer variável vinda da origem (ex.: colunas extras do CSV, {{card_title}}/{{pipeline_stage}} no kanban).

Body (broadcast)

NomeTipoObrigatorioDescricao
namestringSimNome do disparo
descriptionstringNaoDescrição livre do disparo
source_typestringSimcsv | tags | kanban
source_configobjectSimConfig da origem (ver acima)
message_typestringSimcustom | template
message_payloadobjectSimcustom: { messages: [{ type, content }] }; template: { template_name, language, components }
inbox_idsarrayNaoIDs de inbox para envio (WhatsApp/API/SMS)
rotation_modestringNaoround_robin | random | weighted
inbox_weightsobjectNaoPesos por inbox quando rotation_mode=weighted (ex: { "12": 3, "15": 1 })
delay_min_seconds / delay_max_secondsintegerNaoIntervalo de cadência entre envios
pause_every_nintegerNaoPausa de cadência: a cada N envios faz uma pausa longa
pause_duration_secondsintegerNaoDuração (em segundos) da pausa longa disparada por pause_every_n
window_start_time / window_end_timestringNaoJanela de envio (HH:MM, fuso da conta)
allowed_weekdaysarrayNaoDias permitidos (0=domingo .. 6=sábado)
enable_spintaxbooleanNaoVariação de texto via {a|b|c}
enable_follow_upbooleanNaoFollow-up para quem não respondeu
follow_up_after_hours / follow_up_messagemixedNaoQuando e o que enviar no follow-up
start_mode / scheduled_atmixedNaoimmediate | scheduled + data ISO 8601
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/broadcasts" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "broadcast": {
      "name": "Promocao de Junho",
      "source_type": "tags",
      "source_config": { "tag_ids": [12] },
      "message_type": "custom",
      "message_payload": { "messages": [{ "type": "text", "content": "Ola {{nome}}!" }] },
      "inbox_ids": [2]
    }
  }'

Detalhes / Atualizar / Excluir

GET/api/v1/accounts/{account_id}/broadcasts/{id}

Retorna os detalhes de um disparo.

PATCH/api/v1/accounts/{account_id}/broadcasts/{id}

Atualiza um disparo. Enquanto status=pending todos os campos são editáveis; após iniciar, apenas name/description.

DELETE/api/v1/accounts/{account_id}/broadcasts/{id}

Remove o disparo (apenas administradores). Retorna 204.

Pausar / Retomar / Cancelar

POST/api/v1/accounts/{account_id}/broadcasts/{id}/pause

Pausa um disparo em execução (apenas a partir de running).

POST/api/v1/accounts/{account_id}/broadcasts/{id}/resume

Retoma um disparo pausado (apenas a partir de paused).

POST/api/v1/accounts/{account_id}/broadcasts/{id}/cancel

Cancela um disparo. Não permitido se já completed/cancelled/failed.

Duplicar

POST/api/v1/accounts/{account_id}/broadcasts/{id}/duplicate

Cria um novo disparo (status pending) copiando a configuração do disparo de origem. Não copia contatos nem contadores.

Contatos do Disparo

GET/api/v1/accounts/{account_id}/broadcasts/{id}/contacts

Lista os destinatários e o status de envio de cada um.

Query

NomeTipoObrigatorioDescricao
statusstringNaopending | sending | sent | failed | replied | blacklisted | skipped
qstringNaoBusca por telefone ou nome (ILIKE)
limitintegerNaoMax 200, padrão 50
offsetintegerNaoDeslocamento
200Array de contatos do disparo
json
[
  {
    "id": 9001,
    "broadcast_id": 42,
    "phone_number": "+5511999998888",
    "name": "Joao Silva",
    "status": "sent",
    "inbox_id_used": 2,
    "sent_at": "2026-06-02T12:05:00Z",
    "replied_at": null
  }
]

Exportar Contatos

GET/api/v1/accounts/{account_id}/broadcasts/{id}/export

Baixa um CSV com todos os contatos do disparo e o resultado de cada envio. Sem corpo de requisição.

Formato do CSV

Resposta text/csv (Content-Disposition: attachment; filename="broadcast-<id>.csv"). Cabeçalho (em português): telefone,nome,status,enviado_em,erro, uma linha por contato.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/broadcasts/42/export" \
  -H "api_access_token: YOUR_TOKEN" -o broadcast-42.csv

Pré-visualização

Endpoints auxiliares do assistente de criação. Ambos recebem os parâmetros no nível raiz do corpo (sem o wrapper broadcast) e não criam nada.

POST/api/v1/accounts/{account_id}/broadcasts/csv_preview

Valida e pré-visualiza um CSV antes de criar o disparo (retorna as 10 primeiras linhas normalizadas).

Body (nível raiz)

NomeTipoObrigatorioDescricao
csv_contentstringSimConteúdo bruto do CSV (com cabeçalho). A coluna telefone é obrigatória.
200Prévia do CSV (telefone normalizado para E.164)
json
{
  "rows": [
    { "phone": "+5511999998888", "name": "Joao", "variables": { "cidade": "SP" } }
  ],
  "total": 1,
  "errors": []
}

Erros

csv_content ausente ou vazio → 400 ({ "error": "param is missing..." }); CSV sem a coluna obrigatória telefone422.

POST/api/v1/accounts/{account_id}/broadcasts/contacts_preview

Conta quantos contatos uma origem (tags/kanban/csv) resolveria, com uma amostra. Best-effort: origem vazia ou inexistente retorna count 0 (não valida).

Body (nível raiz)

NomeTipoObrigatorioDescricao
source_typestringSimtags | kanban | csv
source_configobjectNaoMesma config do create (tag_ids / funnel_id+stage_ids / csv_rows). Ausente → count 0.
200Contagem + amostra (até 5)
json
{ "count": 128, "sample": [ { "phone": "+5511...", "name": "Joao", "variables": {} } ] }

Blacklist

Números em blacklist são excluídos de qualquer disparo na conta (único por conta). Adicionar e remover exigem administrador.

GET/api/v1/accounts/{account_id}/broadcast_blacklist_entries

Lista os números em blacklist (query: q, limit, offset).

POST/api/v1/accounts/{account_id}/broadcast_blacklist_entries

Adiciona um número à blacklist.

Parâmetros no nível raiz

Diferente do create de disparo, aqui phone_number e reason vão no nível raiz do corpo (não dentro de um wrapper).

Body

NomeTipoObrigatorioDescricao
phone_numberstringSimNúmero a bloquear (E.164)
reasonstringNaoMotivo opcional
DELETE/api/v1/accounts/{account_id}/broadcast_blacklist_entries/{id}

Remove uma entrada da blacklist. Retorna 204.

Webhooks

Assine estes eventos em um webhook de conta para acompanhar o ciclo de vida do disparo:

Eventos

NomeTipoObrigatorioDescricao
broadcast_startedeventNaoDisparo entrou em execução (running)
broadcast_completedeventNaoDisparo concluído (todos os contatos processados)
broadcast_follow_up_senteventNaoFollow-up enviado a um contato que não respondeu

Reenvio de Falhas

POST/api/v1/accounts/{account_id}/broadcasts/{id}/retry_failed

Reenfileira os contatos com status failed do disparo para nova tentativa (apenas falhas transientes).

Métricas de Entrega (read receipts)

O disparo e cada contato expõem os recibos de entrega/leitura, atualizados pelos ACKs do WhatsApp.

Campos do disparo

NomeTipoObrigatorioDescricao
delivered_countintegerNaoTotal de mensagens entregues
read_countintegerNaoTotal de mensagens lidas

Campos do contato

NomeTipoObrigatorioDescricao
delivered_atdatetimeNaoQuando a mensagem foi entregue (null se ainda não)
read_atdatetimeNaoQuando a mensagem foi lida (null se ainda não)
retry_countintegerNaoTentativas de reenvio já feitas
failure_kindstringNaoClassificação da falha (transient | permanent)

Recorrência

No create/update (enquanto pending) um disparo pode recorrer. O agendamento gera novos disparos filhos (parent_broadcast_id) e calcula next_run_at no timezone da conta.

Body (broadcast)

NomeTipoObrigatorioDescricao
recurrence_rulestringNaodaily | weekly | monthly (ausente = disparo único)
recurrence_configobjectNaointerval, time, end_date, max_occurrences, month_day, weekdays[]/days_of_week[]

Destinos de Grupo WhatsApp

Para disparar a grupos (inbox NooviConnect), use source_type="whatsapp_group" e informe os grupos-alvo em broadcast_targets.

broadcast_targets[] (no create)

NomeTipoObrigatorioDescricao
target_kindstringSimTipo do alvo (ex.: 'group')
provider_jidstringSimJID do grupo (ex.: 120363...@g.us)
metadataobjectNaoMetadados livres (ex.: { name })

Regras de Boas-vindas

Mensagem automática enviada quando uma nova conversa é criada em um inbox. CRUD escopado por inbox.

GET/api/v1/accounts/{account_id}/inboxes/{inbox_id}/broadcast_welcome_rules

Lista as regras de boas-vindas do inbox.

POST/api/v1/accounts/{account_id}/inboxes/{inbox_id}/broadcast_welcome_rules

Cria uma regra de boas-vindas.

Body (broadcast_welcome_rule)

NomeTipoObrigatorioDescricao
enabledbooleanNaoAtiva/desativa a regra
message_payloadobjectSimmessages[]: [{ type: "text", content }]
delay_min_secondsintegerNaoAtraso mínimo de cadência
delay_max_secondsintegerNaoAtraso máximo de cadência
pause_every_nintegerNaoPausa a cada N envios
pause_duration_secondsintegerNaoDuração da pausa
window_start_timestringNaoInício da janela de envio (HH:MM)
window_end_timestringNaoFim da janela de envio (HH:MM)
allowed_weekdaysarrayNaoDias da semana permitidos
GET/api/v1/accounts/{account_id}/inboxes/{inbox_id}/broadcast_welcome_rules/{id}

Detalhe de uma regra.

PATCH/api/v1/accounts/{account_id}/inboxes/{inbox_id}/broadcast_welcome_rules/{id}

Atualiza uma regra.

DELETE/api/v1/accounts/{account_id}/inboxes/{inbox_id}/broadcast_welcome_rules/{id}

Remove uma regra. Retorna 204.

Relatório de Engajamento

GET/api/v2/accounts/{account_id}/reports/broadcasts/{id}/engagement_report

Retorna métricas agregadas de engajamento do disparo (taxas de entrega, leitura e resposta) no período.