Follow-ups

Agende mensagens de acompanhamento automáticas em conversas. Configure templates reutilizáveis, automações baseadas em triggers e regras de follow-up por estágio do pipeline.

Escopos de Follow-up

Follow-ups podem ser criados por conversa (scoped) ou gerenciados globalmente na conta. Templates e automações 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. Administradores veem todos; os demais usuários veem apenas os follow-ups que criaram. O conversation_id da URL é o display_id da 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,
      "message": "Ola! Gostaria de saber se teve chance de avaliar nossa proposta.",
      "content": "Ola! Gostaria de saber se teve chance de avaliar nossa proposta.",
      "scheduled_at": 1771596000,
      "title": null,
      "inbox_id": 1,
      "conversation_id": 42,
      "created_at": 1771212000,
      "status": "pending"
    }
  ]
}

Campos do follow-up

message e content trazem o mesmo texto (content é o nome usado na escrita). Datas vêm em epoch (segundos) e conversation_id é o display_id. Quando o envio falhou, o objeto ganha error_message com o motivo.whatsapp_template_name traz o nome do template aprovado do WhatsApp quando o follow-up sai como template (null para mensagem comum). Ao editar um follow-up assim, reenviar o mesmo content só troca data e título; um contentdiferente sem template_params transforma em mensagem comum. Este é o mesmo objeto devolvido por detalhe, criação, edição, cancelamento e reenvio.

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

Retorna a contagem total de follow-ups da conversa.

200Contagem (mesmo recorte de visibilidade da listagem)
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 é o display_id da conversa (per-account, não ID global); ele é resolvido dentro da conta autenticada e a conversa é ligada automaticamente — não envie conversation_id no corpo.

Body (follow_up)

NomeTipoObrigatorioDescricao
contentstringSimConteúdo da mensagem de follow-up. message é aceito como sinônimo (content ganha se os dois vierem)
scheduled_atstring | integerSimData/hora de envio: ISO 8601 (sem offset é interpretado no fuso da conta; com offset ou Z, o instante é absoluto) ou epoch em segundos (13 dígitos são lidos como milissegundos). Valor ilegível retorna 422. Na criação 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, senão retorna 422.
titlestringNaoTítulo do follow-up
follow_up_template_idintegerNaoID do template a usar (da mesma conta)
template_paramsobjectNaoTemplate aprovado do WhatsApp escolhido para uma caixa oficial (nome, idioma, namespace e parâmetros processados)

Resposta e erros

Sucesso responde 201 com o objeto do follow-up. Falha de validação responde 422 com { "error": "..." }. Um corpo sem nenhum campo editável também responde 422, nomeando os campos ignorados. O status nasce pending e não pode ser enviado.

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 não 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. Permitido ao administrador ou a quem criou o follow-up.

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

Atualiza um follow-up pendente (administrador ou quem o criou). Aceita os campos da criação dentro de follow_up; status não é editável. Follow-up que não está pending responde 422 com { error, status } nomeando o status atual — para reativar um follow-up falho use retry_send. Reescrever content sem template_params remove o template do WhatsApp que o follow-up carregava. PUT é aceito como alias.

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

Remove um follow-up pendente. Responde 200 sem corpo; follow-up que não está pending responde 422.

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

Cancela um follow-up pendente sem removê-lo do histórico e responde 200 com o follow-up. Follow-up que não está pending responde 422.

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

Só é possível reenviar follow-ups com status "failed"; os demais respondem 422. Cada follow-up aceita no máximo 5 reenvios manuais — acima disso a resposta é 422. Um follow-up de sequência que já entregou parte dos itens retoma do primeiro item não entregue; os demais são reagendados para cerca de um minuto depois e voltam a pending.

Follow-ups da Conta

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

Lista os follow-ups de toda a conta (todas as conversas), ordenados por data de agendamento. Aceita filtros e paginação opcional. Apenas a ação index existe nesta rota — criar/cancelar é feito na rota aninhada de conversa.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-ups?status=pending&per_page=25&page=1" \
  -H "api_access_token: YOUR_TOKEN" | jq .

Query

NomeTipoObrigatorioDescricao
statusstringNaopending, sent, failed ou cancelled
conversation_idintegerNaoID de exibição da conversa (o número mostrado no painel)
pipeline_card_idintegerNaoFollow-ups ligados a este card do Pipeline
template_idintegerNaoFollow-ups gerados a partir deste template
scheduled_fromstringNaoInício da janela de agendamento (inclusivo), ISO 8601 ou epoch em segundos
scheduled_tostringNaoFim da janela de agendamento (inclusivo), ISO 8601 ou epoch em segundos
pageintegerNaoPágina (padrão 1). Só vale junto com per_page
per_pageintegerNaoItens por página, máximo 100. Sem ele, a resposta traz a lista inteira que casa com os filtros

Paginação

Com per_page, meta traz count, current_page, per_page e total_pages, e uma página além do fim devolve payload vazio. Sem per_page, meta traz só count. Data ilegível em scheduled_from/scheduled_to retorna 422.

200Follow-ups da conta (chaves meta e payload)
json
{
  "meta": { "count": 1, "current_page": 1, "per_page": 25, "total_pages": 1 },
  "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 assíncrono; cada linha agenda um follow-up na conversa correspondente. Requer admin ou a permissão de função 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"
200Importação enfileirada
json
{ "success": true }
422Arquivo ausente ou inválido
json
{ "error": "Failed to upload the import file" }

Templates de Follow-up

Templates reutilizáveis com variáveis dinâmicas para padronizar mensagens de acompanhamento.

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

Lista todos os templates ativos da conta, em ordem alfabética de nome. Qualquer usuário da conta pode listar.

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 não vêm 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 variáveis disponíveis para uso nos templates (nomes planos, não aninhados).

200Variáveis disponíveis (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 responsável" },
    { "name": "card_title", "placeholder": "{{card_title}}", "description": "Título 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 estágio 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)" }
  ]
}
GET/api/v1/accounts/{account_id}/follow-up-templates/{id}

Retorna um template ativo, no mesmo formato de cada item da listagem (sem wrapper). Qualquer usuário da conta pode ler.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Template
json
{
  "id": 3,
  "name": "Acompanhamento pos-proposta",
  "content": "Ola {{contact_name}}, tudo certo?",
  "variables": ["contact_name"],
  "active": true,
  "created_at": 1767225600,
  "updated_at": 1767225600,
  "user_id": 5,
  "user_name": "Joao Silva",
  "attachments": [
    {
      "id": 88,
      "filename": "proposta.pdf",
      "content_type": "application/pdf",
      "byte_size": 204800,
      "url": "/rails/active_storage/blobs/redirect/.../proposta.pdf"
    }
  ],
  "has_attachments": true,
  "items_count": 2,
  "uses_items": true
}

Template removido responde 404

A remoção de template é lógica (active: false). Um template removido não aparece na listagem, e detalhe, edição, pré-visualização, remoção de anexo e as rotas de itens respondem 404 para ele.

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

Cria um novo template.

Body (follow_up_template)

NomeTipoObrigatorioDescricao
namestringSimNome do template (único por conta)
contentstringNaoConteúdo de mensagem única (suporta variáveis como {{contact_name}}). Opcional: templates com itens usam o conteúdo de cada item
activebooleanNaoSe o template está ativo (padrão: true)
attachments[]file[]NaoAnexos do template (multipart/form-data). Enviado FORA do wrapper follow_up_template, como campo top-level attachments[]. Aceito também no PATCH.

Permissão, resposta e erros

Criar, editar e remover templates (e anexos) exige administrador ou a permissão de função personalizada follow_up_manage; sem ela a resposta é 401. Sucesso responde 201 com o objeto do template; validação falha em 422 com { "errors": ["..."] }.

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

Atualiza um template (mesmos campos e permissão da criação). Novos attachments[] são acrescentados aos existentes. Responde 200 com o template. PUT é aceito como alias.

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

Remove um template (soft delete: passa a active=false). Responde 204 sem corpo.

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

Remove um anexo do template. O attachment_id é o id de um item de attachments no objeto do template. Responde 200 com o template atualizado; anexo que não pertence ao template responde 404 com { error: 'Attachment not found' }.

bash
curl -X DELETE "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3/attachments/88" \
  -H "api_access_token: YOUR_TOKEN"

Itens do Template

Todas as rotas de itens exigem permissão de gestão

Inclusive a leitura: listar e detalhar itens exigem administrador ou a permissão follow_up_manage, como a edição do template. Sem ela a resposta é 401. Em template removido, as rotas respondem 404.

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

Lista os itens (mensagens) do template, na ordem de envio (position crescente).

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-up-templates/3/items" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Itens do template (chave payload)
json
{
  "payload": [
    {
      "id": 1,
      "position": 0,
      "delay_seconds": 0,
      "item_type": "text",
      "content": "Ola {{contact_name}}! Tudo certo com a proposta?",
      "whatsapp_template_name": null,
      "whatsapp_template_language": null,
      "whatsapp_template_namespace": null,
      "whatsapp_template_mapping": {},
      "attachment": null,
      "created_at": 1767225600,
      "updated_at": 1767225600
    },
    {
      "id": 2,
      "position": 1,
      "delay_seconds": 86400,
      "item_type": "document",
      "content": null,
      "whatsapp_template_name": null,
      "whatsapp_template_language": null,
      "whatsapp_template_namespace": null,
      "whatsapp_template_mapping": {},
      "attachment": {
        "id": 90,
        "filename": "catalogo.pdf",
        "content_type": "application/pdf",
        "byte_size": 512000,
        "url": "/rails/active_storage/blobs/redirect/.../catalogo.pdf"
      },
      "created_at": 1767225600,
      "updated_at": 1767225600
    }
  ]
}
GET/api/v1/accounts/{account_id}/follow-up-templates/{template_id}/items/{item_id}

Retorna um item do template, no mesmo formato de cada elemento da listagem (sem wrapper). Item de outro template responde 404.

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
contentstringNaoConteúdo da mensagem (suporta variáveis como {{contact_name}}). Obrigatório para item_type text e whatsapp_template; neste último é o texto alternativo (fallback) usado fora do canal oficial.
item_typestringSimTipo do item: text, image, audio, video, document, whatsapp_template
positionintegerNaoPosição do item na sequência (0, 1, 2...). Se omitida ou 0, é anexado ao final.
delay_secondsintegerNaoDelay em segundos após o item anterior (padrão: 0; máximo 86400 = 24h)
attachmentfileNaoAnexo de mídia do item (multipart/form-data). Enviado FORA do wrapper follow_up_template_item, como campo top-level attachment. Aceito também no PATCH.
whatsapp_template_namestringNaoObrigatório 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 parâmetros do template. Formato: { "body": [ { "type": "variable"|"text", "value": "contact_name" } ], "header": { "media_url": "https://cdn.exemplo.com/arquivo.pdf", "media_type": "document", "media_name": "arquivo.pdf" } }. O "header" é obrigatório quando o template aprovado tem cabeçalho de mídia (DOCUMENT/IMAGE/VIDEO): a Meta rejeita o envio sem esse parâmetro. Dentro dele, "media_url" e "media_type" (document, image ou video) são obrigatórios juntos — sem um deles a criação responde 422. A URL precisa ser pública e ter no máximo 2000 caracteres, porque o WhatsApp busca o arquivo no momento do envio. Em inbox WhatsApp oficial fora da janela de 24h envia o template; em WAHA/UazAPI ou dentro da janela envia o content (texto, sem o anexo).
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
    }
  }'

Resposta e erros

Sucesso responde 201 com o item. Validação falha em 422 com { "errors": ["..."] }.

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

Atualiza um item do template (mesmos campos da criação, dentro de follow_up_template_item). Responde 200 com o item. PUT é aceito como alias.

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

Remove um item do template. Responde 204 sem corpo.

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 posição de cada item é definida pelo índice no array. delay_seconds é opcional: omitido, o atraso atual do item é mantido. Sem o array, a resposta é 400; id de item que não pertence ao template, 404. Sucesso responde 200 com { payload } na nova ordem.
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

Pré-visualiza o template com variáveis substituídas.

Body

NomeTipoObrigatorioDescricao
contextobjectNaoObjeto com pares variável: valor para substituir (ex: { "contact_name": "Maria" }). Apenas variáveis suportadas são usadas. Se omitido, retorna o conteúdo 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?"
}

Automações de Follow-up

Configure triggers automáticos para iniciar sequências de follow-up baseados em eventos.

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

Lista as automações de follow-up da conta, da mais recente para a mais antiga (chave payload). Qualquer usuário da conta pode listar.

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

Retorna uma automação, no mesmo formato de cada item da listagem (sem wrapper). Qualquer usuário da conta pode ler; automação de outra conta responde 404.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/follow-up-automations/7" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Automação
json
{
  "id": 7,
  "name": "Follow-up pos-resolucao",
  "trigger_type": "conversation_resolved",
  "trigger_description": "When a conversation is resolved",
  "trigger_config": {},
  "content_mode": "template",
  "ai_instruction": null,
  "follow_up_template_id": 3,
  "follow_up_template_name": "Acompanhamento pos-proposta",
  "delay_minutes": 0,
  "delay_description": "Immediately",
  "send_window": { "enabled": true, "days": [1, 2, 3, 4, 5], "start": "08:00", "end": "18:00" },
  "conditions": {},
  "enabled": true,
  "executions_count": 14,
  "last_executed_at": 1771596000,
  "created_at": 1767225600,
  "updated_at": 1767225600,
  "user_id": 5,
  "user_name": "Joao Silva"
}
POST/api/v1/accounts/{account_id}/follow-up-automations

Cria uma automação de follow-up.

Body (follow_up_automation)

NomeTipoObrigatorioDescricao
namestringSimNome da automação (único por conta)
content_modestringNaoOrigem da mensagem: 'template' (padrão) usa um follow_up_template; 'ai' gera a mensagem por IA no envio.
follow_up_template_idintegerNaoID do template a executar. Obrigatório quando content_mode='template'.
ai_instructionstringNaoInstrução/objetivo do follow-up. Obrigatório quando content_mode='ai'; a IA escreve a mensagem usando esta instrução + o histórico da conversa.
trigger_typestringSimTipo de gatilho: label_added, label_removed, contact_created, conversation_created, conversation_resolved, conversation_inactivity
enabledbooleanNaoSe a automação está ativa (padrão: true)
delay_minutesintegerNaoDelay em minutos antes de executar (padrão: 0). Ignorado para conversation_inactivity.
trigger_configobjectNaoConfiguração específica do gatilho. label_added/label_removed: { label_id }. conversation_inactivity: { inactivity_minutes } (silêncio do cliente desde a última mensagem recebida).
conditionsobjectNaoCondições adicionais para filtrar quando a automação dispara
send_windowobjectNaoJanela de horário de envio. Quando habilitada, follow-ups que cairiam fora do intervalo são adiados para a próxima 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=sábado; 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 após a última 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
    }
  }'

Permissão, resposta e erros

Criar, editar e remover automações exige administrador ou a permissão follow_up_manage; sem ela a resposta é 401. Sucesso responde 201 com o objeto da automação; validação falha em 422 com { "errors": ["..."] }.

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

Atualiza uma automação (mesmos campos e permissão da criação, dentro de follow_up_automation). Responde 200 com a automação. PUT é aceito como alias.

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

Remove uma automação. Responde 204 sem corpo.

Regras de Follow-up por Pipeline

Configure follow-ups automáticos baseados na movimentação de cards entre estágios do pipeline.

Acesso

Estas rotas pertencem ao módulo Pipeline Pro (conta sem o módulo responde 403 com "code": "pipeline_board_disabled"). Pipeline de outra conta ou inexistente responde 404; agente que não é membro do pipeline recebe 403. Para Agent Bot, um pipeline fora do seu escopo (lista agent_bots do pipeline preenchida sem o bot) também responde 404 em todas estas rotas — ler, criar, editar e remover; lista vazia deixa o pipeline aberto a todo bot. Administradores e agentes leem as regras; criar e editar exige administrador, a permissão follow_up_manage ou a permissão pipeline_manage; remover exige administrador ou follow_up_manage. Sem a permissão de escrita a resposta é 401.

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

Lista as regras de follow-up do pipeline, ordenadas por to_stage (chave payload).

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

Retorna uma regra do pipeline, no mesmo formato de cada item da listagem (sem wrapper). Regra de outro pipeline responde 404.

bash
curl -s "https://chat.seudominio.com/api/v1/accounts/1/pipelines/9/follow-up-rules/4" \
  -H "api_access_token: YOUR_TOKEN" | jq .
200Regra
json
{
  "id": 4,
  "pipeline_id": 9,
  "follow_up_template_id": 3,
  "follow_up_template_name": "Acompanhamento pos-proposta",
  "sender_id": 5,
  "sender_name": "Joao Silva",
  "sender_agent_bot_id": null,
  "sender_agent_bot_name": null,
  "content_mode": "template",
  "ai_instruction": null,
  "from_stage": null,
  "to_stage": "proposta",
  "delay_minutes": 1440,
  "delay_description": "1 day",
  "send_window": { "enabled": true, "days": [1, 2, 3, 4, 5], "start": "08:00", "end": "18:00" },
  "enabled": true,
  "conditions": {},
  "created_at": 1767225600,
  "updated_at": 1767225600
}
POST/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules

Cria uma regra de follow-up para o pipeline. Responde 201 com a regra; validação falha em 422 com { errors: [...] }.

Body (pipeline_follow_up_rule)

NomeTipoObrigatorioDescricao
to_stagestringSimID do estágio destino que aciona a regra (ex: "755_entrada_de_lead"). Precisa existir no pipeline
content_modestringNao'template' (padrão) envia um follow_up_template; 'ai' faz a NooviAI redigir a mensagem a partir de ai_instruction e do histórico da conversa
follow_up_template_idintegerNaoID do template a executar (da mesma conta). Obrigatório na criação quando content_mode='template'
ai_instructionstringNaoInstrução para a IA. Obrigatória quando content_mode='ai' (máximo 4096 caracteres)
from_stagestringNaoID do estágio de origem (opcional, filtra apenas cards vindos deste estágio)
delay_minutesintegerNaoDelay em minutos após entrar no estágio (padrão: 0)
enabledbooleanNaoSe a regra está ativa (padrão: true)
sender_idintegerNaoAgente da conta que assina a mensagem. Sem remetente, a autoria segue o responsável do card, depois o responsável da conversa e, por fim, um administrador
sender_agent_bot_idintegerNaoAgent bot que assina a mensagem, no lugar de um humano. Não pode ser enviado junto com sender_id (422)
conditionsobjectNaoCondições adicionais da regra
send_windowobjectNaoJanela de horário de envio. Quando habilitada, follow-ups (incluindo itens de sequência) que cairiam fora do intervalo são adiados para a próxima 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=sábado; end deve ser maior que start.
PATCH/api/v1/accounts/{account_id}/pipelines/{pipeline_id}/follow-up-rules/{id}

Atualiza uma regra (mesmos campos da criação, dentro de pipeline_follow_up_rule). Responde 200 com a regra; validação falha em 422 com { errors: [...] }. PUT é aceito como alias.

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

Remove uma regra. Responde 204 sem corpo.

Relatórios de Follow-ups

Métricas agregadas de follow-ups (taxas de envio, sucesso, falha e cancelamento, além de quebras por status, origem, usuário e template). Disponível na API v2. Requer permissão de visualização de relatórios.

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.
  • status — pending | sent | failed | cancelled
  • source — pipeline | automation | (nulo = manual)
  • user_id — filtra por agente responsável
  • template_id — filtra por template usado
GET/api/v2/accounts/{account_id}/reports/follow-ups

Relatório completo: métricas, quebras por status/origem/usuário/template e série 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 .
200Relatório 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 métricas agregadas (mesmo objeto metrics do relatório completo).

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

Quebra por usuário: { 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 .