Follow-ups

Agende mensagens de acompanhamento automaticas em conversas. Configure templates reutilizaveis, automacoes baseadas em triggers e regras de follow-up por estagio do pipeline.

Escopos de Follow-up

Follow-ups podem ser criados por conversa (scoped) ou gerenciados globalmente na conta. Templates e automacoes permitem escalar o processo de acompanhamento.

Follow-ups da Conversa

GET/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups

Lista follow-ups de uma conversa.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/conversations/42/follow-ups" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Lista de follow-ups (chave payload)
json
{
  "payload": [
    {
      "id": 1,
      "status": "pending",
      "scheduled_at": 1771596000,
      "message": "Ola! Gostaria de saber se teve chance de avaliar nossa proposta.",
      "title": null,
      "inbox_id": 1,
      "conversation_id": 42,
      "created_at": 1771212000
    }
  ]
}
GET/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/count

Retorna a contagem total de follow-ups da conversa.

200Contagem
json
{ "count": 3 }
POST/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups

Agenda um novo follow-up para a conversa. Body envolto em follow_up.

Body envolto em follow_up

Os campos devem estar dentro do wrapper follow_up. O conversation_idna URL e o display_id da conversa (per-account, nao ID global); ele e resolvido dentro da conta autenticada e a conversa e ligada automaticamente — nao envie conversation_id no corpo.

Body (follow_up)

NomeTipoObrigatorioDescricao
contentstringSimConteudo da mensagem de follow-up
scheduled_atstringSimData/hora de envio (ISO 8601). Deve ser no futuro — uma data no passado retorna 422 ("must be in the future").
inbox_idintegerNaoID do inbox para envio (opcional — pode ficar nulo). Se informado, deve pertencer ao mesmo inbox da conversa, senao retorna 422.
titlestringNaoTitulo do follow-up
follow_up_template_idintegerNaoID do template a usar
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/conversations/42/follow-ups" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "follow_up": {
      "content": "Ola! Vi que ainda nao respondeu. Posso ajudar?",
      "scheduled_at": "2026-02-20T10:00:00Z",
      "inbox_id": 1
    }
  }'
GET/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}

Retorna detalhes de um follow-up.

PATCH/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}

Atualiza um follow-up pendente.

DELETE/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}

Remove um follow-up.

POST/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}/cancel

Cancela um follow-up pendente sem remove-lo do historico.

bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/conversations/42/follow-ups/1/cancel" \
  -H "api_access_token: YOUR_TOKEN"
POST/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}/retry_send

Reenvia um follow-up que falhou.

Apenas Follow-ups Falhados

So e possivel reenviar follow-ups com status "failed".

Follow-ups da Conta

GET/api/v1/accounts/{account_id}/follow-ups

Lista todos os follow-ups de toda a conta (todas as conversas). Apenas a acao index existe nesta rota — criar/cancelar e feito na rota aninhada de conversa.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-ups" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Follow-ups da conta (chave payload)
json
{
  "payload": [
    {
      "id": 1,
      "message": "Ola! Posso ajudar?",
      "scheduled_at": 1771596000,
      "title": null,
      "inbox_id": 1,
      "inbox_name": "WhatsApp Business",
      "conversation_id": 42,
      "status": "pending",
      "user_id": 5,
      "user_name": "Joao Silva",
      "created_at": 1771212000
    }
  ]
}

Importar via CSV

POST/api/v1/accounts/{account_id}/follow-ups/import

Importa follow-ups em massa a partir de um CSV (multipart/form-data, campo import_file). Cria um job assincrono; cada linha agenda um follow-up na conversa correspondente. Requer admin ou a permissao de funcao personalizada follow_up_manage. Colunas: conversation_id (display_id), content, scheduled_at (ISO8601) e title (opcional).

bash
curl -s -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-ups/import" \
  -H "api_access_token: YOUR_TOKEN" \
  -F "import_file=@follow_ups.csv"
200Importacao enfileirada
json
{ "success": true }
422Arquivo ausente ou invalido
json
{ "error": "Failed to upload the import file" }

Templates de Follow-up

Templates reutilizaveis com variaveis dinamicas para padronizar mensagens de acompanhamento.

GET/api/v1/accounts/{account_id}/follow-up-templates

Lista todos os templates ativos da conta.

200Lista de templates (chave payload)
json
{
  "payload": [
    {
      "id": 3,
      "name": "Acompanhamento pos-proposta",
      "content": "Template de acompanhamento",
      "variables": ["contact_name"],
      "active": true,
      "items_count": 2,
      "uses_items": true,
      "has_attachments": false,
      "attachments": [],
      "user_id": 5,
      "user_name": "Joao Silva",
      "created_at": 1767225600,
      "updated_at": 1767225600
    }
  ]
}

Itens nao vem na listagem

A listagem traz apenas items_count. Para obter os itens individuais (mensagens) de um template, use GET /follow-up-templates/{template_id}/items.

GET/api/v1/accounts/{account_id}/follow-up-templates/variables

Lista variaveis disponiveis para uso nos templates (nomes planos, nao aninhados).

200Variaveis disponiveis (chave variables)
json
{
  "variables": [
    { "name": "contact_name", "placeholder": "{{contact_name}}", "description": "Nome do contato" },
    { "name": "contact_phone", "placeholder": "{{contact_phone}}", "description": "Telefone do contato" },
    { "name": "contact_email", "placeholder": "{{contact_email}}", "description": "E-mail do contato" },
    { "name": "conversation_id", "placeholder": "{{conversation_id}}", "description": "ID da conversa" },
    { "name": "inbox_name", "placeholder": "{{inbox_name}}", "description": "Nome do canal (inbox)" },
    { "name": "agent_name", "placeholder": "{{agent_name}}", "description": "Nome do agente responsavel" },
    { "name": "card_title", "placeholder": "{{card_title}}", "description": "Titulo do card no pipeline" },
    { "name": "card_value", "placeholder": "{{card_value}}", "description": "Valor do card no pipeline" },
    { "name": "stage_name", "placeholder": "{{stage_name}}", "description": "Nome do estagio atual" },
    { "name": "pipeline_name", "placeholder": "{{pipeline_name}}", "description": "Nome do pipeline" },
    { "name": "current_date", "placeholder": "{{current_date}}", "description": "Data atual (DD/MM/YYYY)" },
    { "name": "current_time", "placeholder": "{{current_time}}", "description": "Hora atual (HH:MM)" }
  ]
}
POST/api/v1/accounts/{account_id}/follow-up-templates

Cria um novo template.

Body (follow_up_template)

NomeTipoObrigatorioDescricao
namestringSimNome do template (unico por conta)
contentstringSimConteudo do template (suporta variaveis como {{contact_name}})
activebooleanNaoSe o template esta ativo (padrao: true)
attachments[]file[]NaoAnexos do template (multipart/form-data). Enviado FORA do wrapper follow_up_template, como campo top-level attachments[]. Aceito tambem no PATCH.
PATCH/api/v1/accounts/{account_id}/follow-up-templates/{id}

Atualiza um template.

DELETE/api/v1/accounts/{account_id}/follow-up-templates/{id}

Remove um template (soft delete).

Itens do Template

POST/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items

Adiciona um item (mensagem) ao template. Body envolto em follow_up_template_item.

Body (follow_up_template_item)

NomeTipoObrigatorioDescricao
contentstringSimConteudo da mensagem (suporta variaveis como {{contact_name}}). Para item_type=whatsapp_template, e o texto alternativo (fallback) usado fora do canal oficial.
item_typestringSimTipo do item: text, image, audio, video, document, whatsapp_template
positionintegerNaoPosicao do item na sequencia (0, 1, 2...). Se omitida ou 0, e anexado ao final.
delay_secondsintegerNaoDelay em segundos apos o item anterior (padrao: 0). Ex: 86400 = 24h
attachmentfileNaoAnexo de midia do item (multipart/form-data). Enviado FORA do wrapper follow_up_template_item, como campo top-level attachment. Aceito tambem no PATCH.
whatsapp_template_namestringNaoObrigatorio quando item_type=whatsapp_template. Nome do template aprovado pela Meta.
whatsapp_template_languagestringNaoIdioma do template aprovado (ex: pt_BR).
whatsapp_template_namespacestringNaoNamespace do template (apenas 360Dialog).
whatsapp_template_mappingobjectNaoMapeamento dos parametros do template. Formato: { "body": [ { "type": "variable"|"text", "value": "contact_name" } ] }. Em inbox WhatsApp oficial fora da janela de 24h envia o template; em WAHA/UazAPI ou dentro da janela envia o content (texto).
bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3/items" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "follow_up_template_item": {
      "item_type": "text",
      "content": "Ola {{contact_name}}! Tudo certo com a proposta?",
      "delay_seconds": 86400
    }
  }'
PATCH/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/{item_id}

Atualiza um item do template.

DELETE/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/{item_id}

Remove um item do template.

POST/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/reorder

Reordena itens do template.

Body

NomeTipoObrigatorioDescricao
itemsarraySimArray de objetos { id, delay_seconds } na nova ordem. A posicao de cada item e definida pelo indice no array.
bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3/items/reorder" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "id": 2, "delay_seconds": 0 },
      { "id": 1, "delay_seconds": 86400 }
    ]
  }'
POST/api/v1/accounts/{account_id}/follow-up-templates/{id}/preview

Pre-visualiza o template com variaveis substituidas.

Body

NomeTipoObrigatorioDescricao
contextobjectNaoObjeto com pares variavel: valor para substituir (ex: { "contact_name": "Maria" }). Apenas variaveis suportadas sao usadas. Se omitido, retorna o conteudo com os placeholders preservados.
bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3/preview" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "context": { "contact_name": "Maria", "agent_name": "Joao" } }'
200Preview renderizado
json
{
  "original": "Ola {{contact_name}}, tudo certo?",
  "rendered": "Ola Maria, tudo certo?",
  "sample": "Ola [Nome do contato], tudo certo?"
}

Automacoes de Follow-up

Configure triggers automaticos para iniciar sequencias de follow-up baseados em eventos.

GET/api/v1/accounts/{account_id}/follow-up-automations

Lista automacoes de follow-up.

POST/api/v1/accounts/{account_id}/follow-up-automations

Cria uma automacao de follow-up.

Body (follow_up_automation)

NomeTipoObrigatorioDescricao
namestringSimNome da automacao (unico por conta)
content_modestringNaoOrigem da mensagem: 'template' (padrao) usa um follow_up_template; 'ai' gera a mensagem por IA no envio.
follow_up_template_idintegerNaoID do template a executar. Obrigatorio quando content_mode='template'.
ai_instructionstringNaoInstrucao/objetivo do follow-up. Obrigatorio quando content_mode='ai'; a IA escreve a mensagem usando esta instrucao + o historico da conversa.
trigger_typestringSimTipo de gatilho: label_added, label_removed, contact_created, conversation_created, conversation_resolved, conversation_inactivity
enabledbooleanNaoSe a automacao esta ativa (padrao: true)
delay_minutesintegerNaoDelay em minutos antes de executar (padrao: 0). Ignorado para conversation_inactivity.
trigger_configobjectNaoConfiguracao especifica do gatilho. label_added/label_removed: { label_id }. conversation_inactivity: { inactivity_minutes } (silencio do cliente desde a ultima mensagem recebida).
conditionsobjectNaoCondicoes adicionais para filtrar quando a automacao dispara
send_windowobjectNaoJanela de horario de envio. Quando habilitada, follow-ups que cairiam fora do intervalo sao adiados para a proxima abertura (no fuso da conta). Formato: { "enabled": true, "days": [1,2,3,4,5], "start": "08:00", "end": "18:00" }. days usa 0=domingo..6=sabado; end deve ser maior que start.
bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-up-automations" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "follow_up_automation": {
      "name": "Follow-up pos-resolucao",
      "follow_up_template_id": 3,
      "trigger_type": "conversation_resolved",
      "enabled": true,
      "send_window": {
        "enabled": true,
        "days": [1, 2, 3, 4, 5],
        "start": "08:00",
        "end": "18:00"
      }
    }
  }'

Exemplo: disparar por inatividade do cliente (1h sem responder apos a ultima mensagem recebida) com mensagem gerada por IA.

bash
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/follow-up-automations" \
  -H "api_access_token: YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "follow_up_automation": {
      "name": "Reengajar inativos (IA)",
      "trigger_type": "conversation_inactivity",
      "trigger_config": { "inactivity_minutes": 60 },
      "content_mode": "ai",
      "ai_instruction": "Reengaje o cliente cordialmente e ofereca ajuda para avancar a negociacao.",
      "enabled": true
    }
  }'
PATCH/api/v1/accounts/{account_id}/follow-up-automations/{id}

Atualiza uma automacao.

DELETE/api/v1/accounts/{account_id}/follow-up-automations/{id}

Remove uma automacao.

Regras de Follow-up por Pipeline

Configure follow-ups automaticos baseados na movimentacao de cards entre estagios do pipeline.

GET/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules

Lista regras de follow-up de um pipeline.

POST/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules

Cria uma regra de follow-up para o pipeline.

Body (pipeline_follow_up_rule)

NomeTipoObrigatorioDescricao
to_stagestringSimID do estagio destino que aciona a regra (ex: "755_entrada_de_lead")
follow_up_template_idintegerSimID do template a executar
from_stagestringNaoID do estagio de origem (opcional, filtra apenas cards vindos deste estagio)
delay_minutesintegerNaoDelay em minutos apos entrar no estagio (padrao: 0)
enabledbooleanNaoSe a regra esta ativa (padrao: true)
send_windowobjectNaoJanela de horario de envio. Quando habilitada, follow-ups (incluindo itens de sequencia) que cairiam fora do intervalo sao adiados para a proxima abertura, no fuso da conta. Formato: { "enabled": true, "days": [1,2,3,4,5], "start": "08:00", "end": "18:00" }. days usa 0=domingo..6=sabado; end deve ser maior que start.
PATCH/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules/{id}

Atualiza uma regra.

DELETE/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules/{id}

Remove uma regra.

Relatorios de Follow-ups

Metricas agregadas de follow-ups (taxas de envio, sucesso, falha e cancelamento, alem de quebras por status, origem, usuario e template). Disponivel na API v2. Requer permissao de visualizacao de relatorios.

Filtros (query) — comuns a todos os endpoints

Todos os endpoints abaixo aceitam os mesmos filtros opcionais via query string:

  • since e until — intervalo de tempo em epoch (segundos Unix). Filtram por scheduled_at. Devem ser enviados juntos.
  • statuspending | sent | failed | cancelled
  • sourcepipeline | automation | (nulo = manual)
  • user_id — filtra por agente responsavel
  • template_id — filtra por template usado
GET/api/v2/accounts/{account_id}/reports/follow-ups

Relatorio completo: metricas, quebras por status/origem/usuario/template e serie temporal.

bash
curl -s "https://chat.seudominio.com/api/v2/accounts/1/reports/follow-ups?since=1769904000&until=1772323200" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Relatorio agregado
json
{
  "metrics": {
    "total": 120,
    "sent": 98,
    "pending": 10,
    "failed": 7,
    "cancelled": 5,
    "success_rate": 81.7,
    "cancellation_rate": 4.2,
    "failure_rate": 5.8,
    "from_pipeline": 60,
    "from_automation": 30,
    "manual": 30,
    "unique_conversations": 85,
    "avg_per_conversation": 1.4
  },
  "by_status": { "sent": 98, "pending": 10, "failed": 7, "cancelled": 5 },
  "by_source": { "pipeline": 60, "automation": 30, "manual": 30 },
  "by_user": [
    { "user_id": 5, "user_name": "Joao Silva", "count": 40, "sent": 35, "success_rate": 87.5 }
  ],
  "by_template": [
    { "template_id": 3, "template_name": "Lembrete 24h", "count": 22, "sent": 20, "success_rate": 90.9 }
  ],
  "timeseries": {
    "labels": ["2026-02-01", "2026-02-02"],
    "sent": [12, 8],
    "scheduled": [15, 10],
    "failed": [1, 0]
  }
}
GET/api/v2/accounts/{account_id}/reports/follow-ups/summary

Apenas o bloco de metricas agregadas (mesmo objeto metrics do relatorio completo).

GET/api/v2/accounts/{account_id}/reports/follow-ups/by_user

Quebra por usuario: { data: [...] } com count, sent e success_rate por agente, ordenado por volume.

GET/api/v2/accounts/{account_id}/reports/follow-ups/by_template

Quebra por template: { data: [...] } com count, sent e success_rate por template, ordenado por volume.

GET/api/v2/accounts/{account_id}/reports/follow-ups/export

Exporta os follow-ups filtrados. Aceita os mesmos filtros de query. Retorna CSV (Accept: text/csv) ou JSON ({ data: [...] }, timestamps em epoch).

bash
# CSV
curl -s "https://chat.seudominio.com/api/v2/accounts/1/reports/follow-ups/export.csv?since=1769904000&until=1772323200" \
  -H "api_access_token: YOUR_TOKEN" -o follow_ups_report.csv

# JSON
curl -s "https://chat.seudominio.com/api/v2/accounts/1/reports/follow-ups/export.json" \
  -H "api_access_token: YOUR_TOKEN" | jq .