Disparador em Massa

Envio em massa via WhatsApp/API/SMS com origem por CSV, etiquetas de contato ou estagio do Kanban. Inclui controles de cadencia (janela de horario, rotacao de inbox, delays, spintax), follow-up e blacklist por conta. As mensagens reusam o fluxo nativo de conversa do NooviChat.

Licenca e respostas

O Disparador esta disponivel em toda licenca NooviChat valida. O acesso tambem depende das permissoes do usuario e do estado operacional da conta. As respostas de listagem sao arrays puros e as de detalhe sao objetos puros (sem wrapper data). A listagem retorna um resumo (id, nome, tipo, status e contadores); os campos completos de configuracao (source_config, message_payload, follow_up_message, inbox_weights) vem 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 pagina (max 100, padrao 50)
offsetintegerNaoDeslocamento para paginacao
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 resolucao 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"] } (estagios do funil — o disparo reusa a conversa ja 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 variaveis do template ({{coluna}}).

Resposta

Em caso de sucesso a criacao retorna HTTP 200 (nao 201) com o objeto do disparo (sem wrapper data). Variaveis suportadas na mensagem: {{nome}}, {{telefone}} e qualquer variavel vinda da origem (ex.: colunas extras do CSV, {{card_title}}/{{pipeline_stage}} no kanban).

Body (broadcast)

NomeTipoObrigatorioDescricao
namestringSimNome do disparo
descriptionstringNaoDescricao 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 cadencia entre envios
pause_every_nintegerNaoPausa de cadencia: a cada N envios faz uma pausa longa
pause_duration_secondsintegerNaoDuracao (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=sabado)
enable_spintaxbooleanNaoVariacao de texto via {a|b|c}
enable_follow_upbooleanNaoFollow-up para quem nao 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 sao editaveis; apos 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 execucao (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. Nao permitido se ja completed/cancelled/failed.

Duplicar

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

Cria um novo disparo (status pending) copiando a configuracao do disparo de origem. Nao copia contatos nem contadores.

Contatos do Disparo

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

Lista os destinatarios 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, padrao 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 requisicao.

Formato do CSV

Resposta text/csv (Content-Disposition: attachment; filename="broadcast-<id>.csv"). Cabecalho (em portugues): 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

Pre-visualizacao

Endpoints auxiliares do assistente de criacao. Ambos recebem os parametros no nivel raiz do corpo (sem o wrapper broadcast) e nao criam nada.

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

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

Body (nivel raiz)

NomeTipoObrigatorioDescricao
csv_contentstringSimConteudo bruto do CSV (com cabecalho). A coluna telefone e obrigatoria.
200Previa 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 obrigatoria 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 (nao valida).

Body (nivel raiz)

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

Blacklist

Numeros em blacklist sao excluidos de qualquer disparo na conta (unico por conta). Adicionar e remover exigem administrador.

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

Lista os numeros em blacklist (query: q, limit, offset).

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

Adiciona um numero a blacklist.

Parametros no nivel raiz

Diferente do create de disparo, aqui phone_number e reason vao no nivel raiz do corpo (nao dentro de um wrapper).

Body

NomeTipoObrigatorioDescricao
phone_numberstringSimNumero 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 execucao (running)
broadcast_completedeventNaoDisparo concluido (todos os contatos processados)
broadcast_follow_up_senteventNaoFollow-up enviado a um contato que nao 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).

Metricas de Entrega (read receipts)

O disparo e cada contato expoem 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 nao)
read_atdatetimeNaoQuando a mensagem foi lida (null se ainda nao)
retry_countintegerNaoTentativas de reenvio ja feitas
failure_kindstringNaoClassificacao da falha (transient | permanent)

Recorrencia

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 unico)
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 automatica enviada quando uma nova conversa e 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 minimo de cadencia
delay_max_secondsintegerNaoAtraso maximo de cadencia
pause_every_nintegerNaoPausa a cada N envios
pause_duration_secondsintegerNaoDuracao da pausa
window_start_timestringNaoInicio 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.

Relatorio de Engajamento

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

Retorna metricas agregadas de engajamento do disparo (taxas de entrega, leitura e resposta) no periodo.