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
/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-upsLista follow-ups de uma conversa.
curl -s "https://chat.seudominio.com/api/v1/accounts/1/conversations/42/follow-ups" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"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
}
]
}/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/countRetorna a contagem total de follow-ups da conversa.
{ "count": 3 }/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-upsAgenda 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)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
content | string | Sim | Conteudo da mensagem de follow-up |
scheduled_at | string | Sim | Data/hora de envio (ISO 8601). Deve ser no futuro — uma data no passado retorna 422 ("must be in the future"). |
inbox_id | integer | Nao | ID do inbox para envio (opcional — pode ficar nulo). Se informado, deve pertencer ao mesmo inbox da conversa, senao retorna 422. |
title | string | Nao | Titulo do follow-up |
follow_up_template_id | integer | Nao | ID 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
}
}'/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}Retorna detalhes de um follow-up.
/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}Atualiza um follow-up pendente.
/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}Remove um follow-up.
/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}/cancelCancela um follow-up pendente sem remove-lo do historico.
curl -X POST "https://chat.seudominio.com/api/v1/accounts/1/conversations/42/follow-ups/1/cancel" \
-H "api_access_token: YOUR_TOKEN"/api/v1/accounts/{account_id}/conversations/{conversation_id}/follow-ups/{id}/retry_sendReenvia um follow-up que falhou.
Apenas Follow-ups Falhados
So e possivel reenviar follow-ups com status "failed".
Follow-ups da Conta
/api/v1/accounts/{account_id}/follow-upsLista 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.
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-ups" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"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
}
]
}Buscar Follow-ups
/api/v1/accounts/{account_id}/search/follow_upsBusca global de follow-ups por titulo e conteudo. O escopo respeita o chamador: administradores veem todos, agentes veem apenas os proprios. Parametros q (opcional — sem ele lista todos) e page (opcional).
curl -s "https://chat.seudominio.com/api/v1/accounts/1/search/follow_ups?q=lembrete" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"payload": {
"follow_ups": [
{
"id": 12,
"title": "Lembrete de proposta",
"content": "Ola! Seguindo sobre a proposta...",
"status": "pending",
"source": "manual",
"scheduled_at": 1771596000,
"conversation_id": 42,
"contact": { "id": 7, "name": "Maria" }
}
]
}
}conversation_id e o ID interno, nao o display_id
O campo conversation_id retornado aqui (e nas listagens de follow-up) e o ID interno da conversa, nao o display_id por conta que as rotas de conversa usam no caminho da URL. Para abrir a conversa via API, use o display_id obtido na API de Conversas.
Importar via CSV
/api/v1/accounts/{account_id}/follow-ups/importImporta 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).
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"{ "success": true }{ "error": "Failed to upload the import file" }Templates de Follow-up
Templates reutilizaveis com variaveis dinamicas para padronizar mensagens de acompanhamento.
/api/v1/accounts/{account_id}/follow-up-templatesLista todos os templates ativos da conta.
{
"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.
/api/v1/accounts/{account_id}/follow-up-templates/variablesLista variaveis disponiveis para uso nos templates (nomes planos, nao aninhados).
{
"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)" }
]
}/api/v1/accounts/{account_id}/follow-up-templatesCria um novo template.
Body (follow_up_template)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
name | string | Sim | Nome do template (unico por conta) |
content | string | Sim | Conteudo do template (suporta variaveis como {{contact_name}}) |
active | boolean | Nao | Se o template esta ativo (padrao: true) |
attachments[] | file[] | Nao | Anexos do template (multipart/form-data). Enviado FORA do wrapper follow_up_template, como campo top-level attachments[]. Aceito tambem no PATCH. |
/api/v1/accounts/{account_id}/follow-up-templates/{id}Atualiza um template.
/api/v1/accounts/{account_id}/follow-up-templates/{id}Remove um template (soft delete).
Itens do Template
/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/itemsAdiciona um item (mensagem) ao template. Body envolto em follow_up_template_item.
Body (follow_up_template_item)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
content | string | Sim | Conteudo da mensagem (suporta variaveis como {{contact_name}}). Para item_type=whatsapp_template, e o texto alternativo (fallback) usado fora do canal oficial. |
item_type | string | Sim | Tipo do item: text, image, audio, video, document, whatsapp_template |
position | integer | Nao | Posicao do item na sequencia (0, 1, 2...). Se omitida ou 0, e anexado ao final. |
delay_seconds | integer | Nao | Delay em segundos apos o item anterior (padrao: 0). Ex: 86400 = 24h |
attachment | file | Nao | Anexo 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_name | string | Nao | Obrigatorio quando item_type=whatsapp_template. Nome do template aprovado pela Meta. |
whatsapp_template_language | string | Nao | Idioma do template aprovado (ex: pt_BR). |
whatsapp_template_namespace | string | Nao | Namespace do template (apenas 360Dialog). |
whatsapp_template_mapping | object | Nao | Mapeamento 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). |
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
}
}'/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/{item_id}Atualiza um item do template.
/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/{item_id}Remove um item do template.
/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/reorderReordena itens do template.
Body
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
items | array | Sim | Array de objetos { id, delay_seconds } na nova ordem. A posicao de cada item e definida pelo indice no array. |
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 }
]
}'/api/v1/accounts/{account_id}/follow-up-templates/{id}/previewPre-visualiza o template com variaveis substituidas.
Body
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
context | object | Nao | Objeto com pares variavel: valor para substituir (ex: { "contact_name": "Maria" }). Apenas variaveis suportadas sao usadas. Se omitido, retorna o conteudo com os placeholders preservados. |
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" } }'{
"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.
/api/v1/accounts/{account_id}/follow-up-automationsLista automacoes de follow-up.
/api/v1/accounts/{account_id}/follow-up-automationsCria uma automacao de follow-up.
Body (follow_up_automation)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
name | string | Sim | Nome da automacao (unico por conta) |
content_mode | string | Nao | Origem da mensagem: 'template' (padrao) usa um follow_up_template; 'ai' gera a mensagem por IA no envio. |
follow_up_template_id | integer | Nao | ID do template a executar. Obrigatorio quando content_mode='template'. |
ai_instruction | string | Nao | Instrucao/objetivo do follow-up. Obrigatorio quando content_mode='ai'; a IA escreve a mensagem usando esta instrucao + o historico da conversa. |
trigger_type | string | Sim | Tipo de gatilho: label_added, label_removed, contact_created, conversation_created, conversation_resolved, conversation_inactivity |
enabled | boolean | Nao | Se a automacao esta ativa (padrao: true) |
delay_minutes | integer | Nao | Delay em minutos antes de executar (padrao: 0). Ignorado para conversation_inactivity. |
trigger_config | object | Nao | Configuracao especifica do gatilho. label_added/label_removed: { label_id }. conversation_inactivity: { inactivity_minutes } (silencio do cliente desde a ultima mensagem recebida). |
conditions | object | Nao | Condicoes adicionais para filtrar quando a automacao dispara |
send_window | object | Nao | Janela 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. |
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.
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
}
}'/api/v1/accounts/{account_id}/follow-up-automations/{id}Atualiza uma automacao.
/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.
/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rulesLista regras de follow-up de um pipeline.
/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rulesCria uma regra de follow-up para o pipeline.
Body (pipeline_follow_up_rule)
| Nome | Tipo | Obrigatorio | Descricao |
|---|---|---|---|
to_stage | string | Sim | ID do estagio destino que aciona a regra (ex: "755_entrada_de_lead") |
follow_up_template_id | integer | Sim | ID do template a executar |
from_stage | string | Nao | ID do estagio de origem (opcional, filtra apenas cards vindos deste estagio) |
delay_minutes | integer | Nao | Delay em minutos apos entrar no estagio (padrao: 0) |
enabled | boolean | Nao | Se a regra esta ativa (padrao: true) |
send_window | object | Nao | Janela 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. |
/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules/{id}Atualiza uma regra.
/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:
sinceeuntil— intervalo de tempo em epoch (segundos Unix). Filtram porscheduled_at. Devem ser enviados juntos.status—pending|sent|failed|cancelledsource—pipeline|automation| (nulo = manual)user_id— filtra por agente responsaveltemplate_id— filtra por template usado
/api/v2/accounts/{account_id}/reports/follow-upsRelatorio completo: metricas, quebras por status/origem/usuario/template e serie temporal.
curl -s "https://chat.seudominio.com/api/v2/accounts/1/reports/follow-ups?since=1769904000&until=1772323200" \
-H "api_access_token: YOUR_TOKEN" | jq .{
"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]
}
}/api/v2/accounts/{account_id}/reports/follow-ups/summaryApenas o bloco de metricas agregadas (mesmo objeto metrics do relatorio completo).
/api/v2/accounts/{account_id}/reports/follow-ups/by_userQuebra por usuario: { data: [...] } com count, sent e success_rate por agente, ordenado por volume.
/api/v2/accounts/{account_id}/reports/follow-ups/by_templateQuebra por template: { data: [...] } com count, sent e success_rate por template, ordenado por volume.
/api/v2/accounts/{account_id}/reports/follow-ups/exportExporta os follow-ups filtrados. Aceita os mesmos filtros de query. Retorna CSV (Accept: text/csv) ou JSON ({ data: [...] }, timestamps em epoch).
# 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 .