API para sistemas externos

Hooks de Campanha

Endpoints para sistemas externos disparar ações ou puxar dados de uma campanha F19 (ex.: fazer o WhatsApp da campanha chamar um contato que a equipe está abordando).

Como funciona

Base URL
https://www.hook.w19.com.br/campanha
Formato
JSON (Content-Type: application/json)
Autenticação
token por campanha — header X-Hook-Token ou campo token
Charset
UTF-8 (emojis e acentos suportados)
Cada campanha tem um token próprio, entregue pela equipe F19. Ele autoriza chamadas somente para aquele id_campaign. Guarde-o como segredo (não versione em repositório público).
HookMétodoStatusO que faz
send_contact_campaign POST ATIVO WhatsApp da campanha envia mensagem ao contato + salva na agenda como 🟡 CA - …
list_dispatched_contacts GET ATIVO Lista os contatos que receberam disparo da campanha (nome, telefone, data).
save_contact POST ATIVO Salva o contato na agenda de todas as linhas WhatsApp da campanha (ou só numa).
send_message POST ATIVO Envia mensagem(ns) personalizada(s) por uma linha da campanha (aleatória ou específica).
(próximos) EM BREVE status de contato, agendamento, etc.

POST  send_contact_campaign

Faz o WhatsApp da campanha chamar um contato que a equipe está abordando. Ao receber, o F19:

1. Envia a mensagem da campanha para o contato.
2. Salva o contato na agenda do WhatsApp da campanha como 🟡 CA - <Nome> <Sobrenome> - <data> - <equipe>.

POST https://www.hook.w19.com.br/campanha/send_contact_campaign

Campos (JSON)

CampoTipoObrig.Descrição
id_campaignintsimID da campanha no F19.
tokenstringsim*Token da campanha. *Pode ir no header X-Hook-Token em vez do corpo.
contact_first_namestringsimPrimeiro nome do contato. (alias: nome)
contact_last_namestringnãoSobrenome do contato. (alias: sobrenome)
contact_phonestringsimTelefone E.164 (5519999999999). Sem DDI assume Brasil. (alias: telefone)
apoiadorstringnãosim cadastra o contato como apoiador da campanha — aparece em ?page=apoiador mesmo sem conectar WhatsApp (atribuído a quem abordou, via equipe_telefone).
contact_instagramstringnão@ ou URL do Instagram. (alias: instagram)
datastringnãoData da abordagem (ex.: 20/08). Padrão: hoje.
equipestringnãoRótulo da equipe p/ agenda (ex.: Equipe Murilo).
equipe_nomestringnãoNome de quem abordou (vira "<primeiro nome> passou seu numero").
equipe_telefonestringnãoTelefone de quem abordou (registro).
from_namestringnãoOverride do "<X> aqui". Padrão: 1º nome da campanha.
message_templatestringnãoOverride da mensagem. Cada linha iniciada por - vira uma mensagem separada. Placeholders: {contato} {campanha} {equipe}.
forceboolnãotrue reenvia mesmo se o contato já foi processado.

Exemplos

curl -X POST https://www.hook.w19.com.br/campanha/send_contact_campaign \
  -H "Content-Type: application/json" \
  -H "X-Hook-Token: SEU_TOKEN_DA_CAMPANHA" \
  -d '{
    "id_campaign": 22,
    "contact_first_name": "Vivian",
    "contact_last_name": "Amaral",
    "contact_phone": "5519999999999",
    "apoiador": "nao",
    "contact_instagram": "@vivian",
    "data": "20/08",
    "equipe": "Equipe Murilo",
    "equipe_nome": "Murilo Coghi",
    "equipe_telefone": "5519991277010"
  }'
<?php
$payload = [
  "id_campaign"        => 22,
  "contact_first_name" => "Vivian",
  "contact_last_name"  => "Amaral",
  "contact_phone"      => "5519999999999",
  "apoiador"           => "nao",
  "data"               => "20/08",
  "equipe"             => "Equipe Murilo",
  "equipe_nome"        => "Murilo Coghi",
];
$ch = curl_init("https://www.hook.w19.com.br/campanha/send_contact_campaign");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST           => true,
  CURLOPT_HTTPHEADER     => [
    "Content-Type: application/json",
    "X-Hook-Token: SEU_TOKEN_DA_CAMPANHA",
  ],
  CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
]);
$resp = curl_exec($ch);
echo $resp;
const r = await fetch("https://www.hook.w19.com.br/campanha/send_contact_campaign", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Hook-Token": "SEU_TOKEN_DA_CAMPANHA",
  },
  body: JSON.stringify({
    id_campaign: 22,
    contact_first_name: "Vivian",
    contact_last_name: "Amaral",
    contact_phone: "5519999999999",
    data: "20/08",
    equipe: "Equipe Murilo",
    equipe_nome: "Murilo Coghi",
  }),
});
console.log(await r.json());

Resposta

{
  "ok": true,
  "contact_phone": "5519999999999",
  "message_sent": true,
  "messages": 3,
  "message_id": "3EB0...",
  "contact_added": true,
  "apoiador_registered": true,
  "agenda_name": "🟡 CA - Vivian Amaral - 20/08 - Equipe Murilo",
  "campaign": "Murilo Coghi",
  "line_phone": "5519982085305",
  "errors": []
}

apoiador_registered: true cadastrado (ou já era) · null não pediu (apoiador≠sim) · false erro.

Mensagem enviada ao contato

São enviadas como 3 mensagens separadas (cada bloco chega em sequência, ~1,2s entre elas):

[1] Oi Vivian, Murilo aqui ... Murilo passou seu numero.
    Já salva o meu contato 🙏🏻

[2] Quando puder acessa o site, para ver o cronograma das aulas do rotina
    https://araras.org/rotina/

[3] Mas me fala ... Gostou do projeto?

Códigos de retorno

HTTPSignificado
200OK (enviado + salvo). skipped:true = já processado antes.
401token inválido ou ausente.
404campanha não encontrada.
405método não é POST.
422campos obrigatórios ausentes / telefone inválido.
503campanha sem linha WhatsApp conectada.
502falha ao enviar pela Z-API (ver errors).
Idempotência: cada contato é processado uma vez por campanha. Reenviar o mesmo contact_phone retorna skipped:true — passe force:true para reenviar.

GET  list_dispatched_contacts

Retorna os contatos que receberam disparo da campanha (módulo DISPAROS + listas de transmissão dos apoiadores), deduplicados por telefone — com nome, telefone e data do disparo mais recente.

GET https://www.hook.w19.com.br/campanha/list_dispatched_contacts

Parâmetros

CampoTipoObrig.Descrição
id_campaignintsimID da campanha.
tokenstringsim*Token da campanha. *Pode ir no header X-Hook-Token.
limitintnãoMáximo de contatos (0 ou ausente = todos).
offsetintnãoDeslocamento p/ paginação.

Exemplo

curl "https://www.hook.w19.com.br/campanha/list_dispatched_contacts?id_campaign=22&limit=100" \
  -H "X-Hook-Token: SEU_TOKEN_DA_CAMPANHA"

Resposta

{
  "ok": true,
  "campaign": "Murilo Coghi",
  "total": 2943,
  "contacts": [
    { "nome": "Milene Guedes", "telefone": "5519996823976", "data": "01/09/2026" },
    { "nome": "Val Academia",  "telefone": "5519971265723", "data": "31/08/2026" }
  ]
}

Inclui quem recebeu por qualquer disparo da campanha (drips do módulo DISPAROS e LTs dos apoiadores). data = disparo mais recente.

POST  save_contact

Salva um contato na agenda do(s) WhatsApp(s) da campanha. Como pode haver várias linhas, salva em todas as conectadas por padrão; com numerocampanha específico, só nela.

POST https://www.hook.w19.com.br/campanha/save_contact

Parâmetros

CampoTipoObrig.Descrição
id_campaignintsimID da campanha.
tokenstringsim*Token. *ou header X-Hook-Token.
nomestringsimRótulo pronto p/ agenda (ex.: 🟢RA - Flavia Caroline - Yara - 01/09).
contact_phonestringsimTelefone do contato. (alias: numero, telefone)
numerocampanhastringnãoany (padrão) = salva em todas as linhas conectadas · número = só nessa linha.

Exemplo

curl -X POST https://www.hook.w19.com.br/campanha/save_contact \
  -H "Content-Type: application/json" -H "X-Hook-Token: SEU_TOKEN" \
  -d '{"id_campaign":22,"nome":"🟢RA - Flavia Caroline - Yara - 01/09","contact_phone":"19971338253","numerocampanha":"any"}'
{ "ok": true, "contact_phone": "5519971338253", "saved_lines": 2, "total_lines": 2, "failed_lines": [] }

POST  send_message

Envia mensagem(ns) personalizada(s) a um contato por uma linha da campanha. Cada item de msgs é uma mensagem separada. numerocampanha: any sorteia entre as linhas conectadas; número específico envia por ela.

POST https://www.hook.w19.com.br/campanha/send_message

Parâmetros

CampoTipoObrig.Descrição
id_campaignintsimID da campanha.
tokenstringsim*Token. *ou header X-Hook-Token.
numerostringsimTelefone do contato. (alias: contact_phone)
msgsarraysim*Lista de mensagens (1 balão cada). *ou message (texto; - quebra em várias).
numerocampanhastringnãoany (padrão) sorteia linha conectada · número = envia por essa linha.

Exemplo

curl -X POST https://www.hook.w19.com.br/campanha/send_message \
  -H "Content-Type: application/json" -H "X-Hook-Token: SEU_TOKEN" \
  -d '{"id_campaign":22,"numero":"19971338253","numerocampanha":"any",
       "msgs":["Oi, Flavia... consegue entrar na comunidade para receber as aulas?",
               "*Convite Comunidade*\nhttps://chat.whatsapp.com/EbBc0Cm1r7EJjbwqWx1Tup"]}'
{ "ok": true, "contact_phone": "5519971338253", "from_line": "5519982085305", "sent": 2, "messages": 2 }