Réguas e acompanhamento

Uma Régua programa uma sequência de Templates. O alvo pode ser um contato, uma oportunidade ou uma demanda. Cada ocorrência mantém seu próprio histórico.

Configuração e API

Use journeys:read para consultar e journeys:write para configurar ou controlar. A Conta vem da chave de API. Esta superfície exige chave live; chaves sandbox recebem 403 sandbox_forbidden. IDs de outro cliente são recusados.

Além da API REST, os pacotes publicados incluem Réguas: o SDK (@botozap/sdk 0.7.0) tem o recurso journeys (list, get, create, update, delete, control, runs, enroll, getRun, controlRun), a CLI (@botozap/cli 0.4.0) tem botozap journeys e o MCP (@botozap/mcp 0.5.0) tem as ferramentas list_journeys, get_journey, create_journey, update_journey, archive_journey, control_journey, list_journey_runs, enroll_journey, get_journey_run e control_journey_run. Veja SDK, CLI e MCP.

Método e caminhoOperação
GET /api/v1/journeysListar Réguas. Filtro customer_id (404 se o Cliente não for da conta); paginação por cursor com limit e after.
POST /api/v1/journeysCriar a configuração completa com steps. Responde 201 com a definição completa, com steps, no mesmo formato do GET.
GET /api/v1/journeys/{id}Ler configuração, passos e version. customer_id opcional confere o dono.
PUT /api/v1/journeys/{id}Substituir a configuração inteira, com a version atual no corpo. Sem status, mantém o estado atual. Responde a definição completa, com steps.
DELETE /api/v1/journeys/{id}?version=NArquivar preservando histórico (igual a action: archive).
POST /api/v1/journeys/{id}/control{ action: pause | resume | archive, version }. resume confere os templates como a ativação.
GET /api/v1/journeys/{id}/runsListar execuções da Régua.
POST /api/v1/journeys/{id}/runsProgramar uma ocorrência manualmente.
GET /api/v1/journey-runs/{id}Ler uma execução com seus passos.
POST /api/v1/journey-runs/{id}/control{ action: stop } ou { action: acknowledge, note }.

Alterações concorrentes retornam 409 conflict: o PUT, o DELETE e o control exigem a version atual. Configuração inválida retorna 422 validation_error, com a mensagem do motivo. Régua, contato ou vínculo inexistente retorna 404 not_found.

Contrato da configuração

O corpo do POST e do PUT é a configuração inteira, exceto status no PUT: sem ele, a Régua mantém o estado atual. date_field_key, stage_id, demand_status e appointment_service_id de outro gatilho são ignorados e gravados como null.

CampoRegraPadrão
customer_idObrigatório. UUID de um Cliente da conta.—
nameObrigatório, 1 a 160 caracteres.—
statusactive ou paused. Gravar ou manter a Régua ativa exige todos os templates APPROVED. No POST, ausente vale paused; no PUT, ausente mantém o estado atual.paused
target_kindcontact, opportunity ou demand.contact
trigger_kindcontact_date, stage_entered, appointment ou demand_status.contact_date
date_field_keyCom contact_date: chave de um campo personalizado do tipo data. O valor no contato é AAAA-MM-DD.—
stage_idCom stage_entered: UUID de uma etapa do Cliente.—
demand_statusCom demand_status: open, in_progress, waiting_customer.—
appointment_service_idCom appointment, opcional: serviço da Agenda do Cliente. Ausente, vale qualquer serviço.null
offset_daysCom contact_date: dias antes (negativo) ou depois da data, de −3.660 a 3.660.0
offset_hoursCom appointment: horas antes (negativo) ou depois do horário, de −87.840 a 87.840.0
yearlyCom contact_date: repete a data todo ano. 29/02 cai em 28/02 em ano comum.true
stop_on_replyInterrompe quando o contato responde.true
stop_on_exitInterrompe quando o alvo sai da etapa ou do estado do gatilho.true
send_start_hourInício da janela de envio, 0 a 23, horário de Brasília.9
send_end_hourFim da janela, 1 a 24, maior que o início.20
stepsObrigatório, 1 a 50 passos, na ordem de envio.—
steps[].template_idUUID de um template da conta numa conexão do mesmo Cliente e do mesmo ambiente da chave.—
steps[].delay_minutesEspera antes do passo, de 0 a 525.600 (um ano). No primeiro passo conta a partir do gatilho; nos seguintes, a partir do envio anterior.—
steps[].variable_mapObjeto slot → fonte. Slots "1" a "99", valores até 200 caracteres.{}

Para gravar com status: "active", todos os templates dos passos precisam estar APPROVED numa conexão do Cliente; senão a resposta é 422 validation_error com a mensagem template_unavailable e nada muda. A mesma regra vale para um PUT sem status numa Régua ativa e para action: resume, que recusa a retomada e mantém a Régua pausada. Uma Régua pausada aceita templates ainda em análise. Se um template perder a aprovação com a Régua já ativa, o passo termina com template_unavailable no envio. Uma Régua arquivada não pode ser editada nem retomada (422).

A edição troca a sequência para as próximas ocorrências. Cada ocorrência já programada guarda uma cópia dos passos em snapshot e segue com ela. Pausar suspende o envio de passos (as execuções abertas esperam e seguem ao retomar); arquivar também interrompe as execuções abertas com archived. pause_reason indica manual, stage_deleted (a etapa do gatilho foi apagada), pending_template (modelo pronto aguardando aprovação do template) ou, num modelo pronto cujo template a Meta tirou de uso, template_rejected, template_paused ou template_disabled. Arquivar libera o modelo pronto para ser usado de novo no mesmo cliente. Todo PUT limpa pause_reason, mesmo quando a Régua continua pausada.

Gatilho e alvo

trigger_kindtarget_kindExigeQuando programa
contact_datecontactdate_field_keyNo dia da data + offset_days, a partir de send_start_hour, para contatos do Cliente com o campo preenchido. Só programa no próprio dia de envio (horário de Brasília): com yearly: false, uma data de envio que já passou nunca é programada; com yearly: true, vale a próxima ocorrência.
stage_enteredcontact, opportunitystage_idQuando o contato entra na etapa, ou quando uma oportunidade aberta entra nela.
appointmentcontactappointment_service_id (opcional)Horário do agendamento + offset_hours, para agendamentos criados depois da Régua. Cancelado, falta ou (com offset até 0) concluído não programa; reagendar encerra a ocorrência com rescheduled e permite uma nova no novo horário.
demand_statusdemanddemand_statusQuando a demanda entra no estado configurado.

Todo horário é ajustado à janela send_start_hour–send_end_hour no horário de Brasília: um passo que cairia fora dela sai no próximo início de janela.

Variáveis

variable_map preenche as variáveis do corpo do template: a chave é o número do slot ({{1}} é "1") e o valor é uma fonte, por exemplo {"1":"contact.name","2":"customer.name"}. Qualquer outro texto é enviado literalmente; prefira o prefixo text: para deixar a intenção explícita.

FonteValor
contact.nameNome de perfil do contato.
contact.field:<chave>Campo personalizado do contato. Booleano vira "Sim"/"Não"; campo vazio vira texto vazio.
customer.nameNome do Cliente dono da Régua.
appointment.dateData do agendamento, como 25/09/2026 (só em Réguas de agendamento).
appointment.timeHora do agendamento, como 14:30 (só em Réguas de agendamento).
appointment.datetimeData por extenso e hora, como "25 de setembro de 2026 às 14:30" (só em Réguas de agendamento).
text:<valor>Texto fixo, igual para todos os contatos.

Modelos prontos

O painel (Automações) oferece um catálogo de modelos prontos, como lembrete de horário, pós-atendimento, aniversário e boas-vindas. Eles são ativados só pelo painel, que cria os templates e a Régua. Pela API, uma Régua criada assim aparece como qualquer outra, com catalog_key preenchido; o campo é só leitura.

Execuções

Cada ocorrência de uma Régua para um alvo é uma execução, com um passo por template. Estados da execução:

statusSignificado
scheduledProgramada; nenhum passo saiu ainda.
runningPelo menos um passo foi reivindicado pelo worker.
completedTodos os passos foram enviados.
stoppedInterrompida por regra (resposta, consentimento, saída, manual…). Veja stop_reason.
failedUm passo falhou ou ficou sem confirmação. Veja stop_reason.

GET /api/v1/journeys/{id}/runs lista as execuções de uma Régua, das mais novas para as mais antigas, com id, contact_id, occurrence_key, status, stop_reason, opportunity_id, demand_id, finished_at e created_at. A paginação é por cursor (limit, after). Não há filtro de status nem uma lista geral de execuções de todas as Réguas: consulte Régua por Régua ou use o evento abaixo.

Programar uma ocorrência

O worker programa as ocorrências sozinho a partir do gatilho. POST /api/v1/journeys/{id}/runs programa uma manualmente, numa Régua ativa:

  • contact_id: obrigatório, contato do mesmo Cliente e do mesmo ambiente da Régua.
  • occurrence_key: obrigatório, até 200 caracteres. É a chave de idempotência: a mesma chave para o mesmo contato na mesma Régua não cria outra execução.
  • due_at: ISO 8601 do primeiro passo; padrão agora. O envio respeita a janela de horário.
  • opportunity_id ou demand_id: obrigatório conforme o target_kind, de uma oportunidade aberta na etapa ou de uma demanda no estado configurado.
  • appointment_id: obrigatório em Réguas de agendamento; em outros gatilhos é recusado com 422.

Sucesso responde 201 com { id }. 409 not_enrolled significa que nada foi programado: a chave já existe, a Régua não está ativa, ou o alvo não cumpre a regra (oportunidade fora da etapa, demanda em outro estado, agendamento cancelado ou de outro serviço). Repetir a mesma chave é seguro.

Ler uma execução

GET /api/v1/journey-runs/{id} devolve todos os campos da execução (inclusive journey_id, customer_id, appointment_id, started_at, resolved_at e resolution_note) e steps, um item por passo com id, position, due_at, status, error, skip_reason, external_id, message_id, delivered_at, read_at e snapshot (a cópia do passo usada nesta ocorrência).

status do passoSignificado
pendingAguardando. Passos depois do próximo vêm com due_at "infinity" até o anterior sair.
sendingReivindicado pelo worker.
sentAceito pela Meta; external_id é o wamid e delivered_at/read_at chegam depois.
skippedNão enviado porque a execução parou; skip_reason diz por quê.
failedRecusa comprovada ou bloqueio antes do envio; error diz por quê.
unconfirmedResposta ambígua depois de iniciar o envio (error: unconfirmed_send). Não há reenvio automático.

Interromper ou assumir

POST /api/v1/journey-runs/{id}/control com { "action": "stop" } interrompe uma execução aberta com manual; numa execução já encerrada, devolve o estado sem mudar nada. Se um passo estiver no meio da chamada à Meta, a resposta é 409 conflict: espere alguns segundos e tente de novo.

{ "action": "acknowledge", "note": "…" } registra que a equipe assumiu uma execução failed ou stopped. note é obrigatória, até 2.000 caracteres. A decisão fica em resolved_at e resolution_note, sem reenviar e sem apagar o erro original. Em outro estado, ou sem nota, a resposta é 422.

Consentimento e interrupção

Passo de template MARKETING exige consentimento de marketing concedido no momento do envio: sem registro, a execução para com no_consent; revogado, com opted_out. Templates UTILITY e AUTHENTICATION dispensam consentimento. Isso é mais estrito que nas Transmissões, que só excluem quem revogou. Palavra de saída de marketing não cancela uma sequência exclusivamente UTILITY ou AUTHENTICATION.

A situação do consentimento, do template, da etapa, do desfecho e da resposta é conferida novamente antes da chamada à Meta. Uma requisição já iniciada pode terminar após uma interrupção. stop_on_reply interrompe ao receber resposta; stop_on_exit interrompe quando o alvo sai da etapa ou estado. Oportunidades encerradas e demandas resolvidas encerram o acompanhamento daquela entidade. Uma pessoa pode ter várias oportunidades independentes.

Motivos de parada e falha

stop_reason da execução usa os códigos abaixo. Os passos que não chegaram a sair recebem o mesmo código em skip_reason; o passo que falhou traz o código em error.

CódigoExecuçãoQuando
repliedstoppedO contato respondeu e stop_on_reply está ligado.
opted_outstoppedO contato revogou o consentimento de marketing. Não afeta sequências só com templates UTILITY ou AUTHENTICATION.
no_consentstoppedPasso de marketing sem consentimento concedido.
entity_exitedstoppedOportunidade encerrada, demanda resolvida ou, com stop_on_exit, o alvo saiu da etapa ou do estado.
pausedstoppedA Régua foi pausada no instante do envio.
manualstoppedaction: stop pela API ou pelo painel.
archivedstoppedA Régua foi arquivada.
template_unavailablestopped ou failedTemplate não aprovado ou fora da conexão do contato.
appointment_cancelledstoppedAgendamento cancelado ou marcado como falta.
appointment_completedstoppedComparecimento registrado. Só interrompe Réguas com offset_hours até 0, como lembretes.
appointment_deletedstoppedAgendamento apagado.
appointment_unavailablestoppedAgendamento cancelado, com falta, concluído ou de outro serviço no instante do envio.
rescheduledstoppedAgendamento mudou de horário ou de serviço.
due_passedstoppedO horário do primeiro passo já tinha passado quando o agendamento foi lido.
channel_unavailablestopped ou failedContato sem número de WhatsApp utilizável.
not_connectedfailedNúmero sem conexão ativa ou sem token.
capacityfailedA conta do WhatsApp Business está banida ou restrita, ou não foi possível verificar.
quotafailedQuota mensal de templates esgotada.
unconfirmed_sendfailedEnvio iniciado sem confirmação da Meta.
invalid_valuesfailedFaltou o valor de uma variável do template (por exemplo, o contato sem nome ou sem o campo usado).
dispatch_blockedfailedA conversa do contato tinha outro envio em andamento ou aguardando conciliação.
<mensagem da Meta>failedRecusa comprovada da Meta, com o texto do erro precedido do código numérico quando a Meta informa, como (#131026) Message undeliverable.

Quota, falhas e avisos

Cada passo enviado consome um template da quota mensal do plano, a mesma dos envios avulsos e das transmissões (veja Quota mensal). A reserva acontece imediatamente antes do envio e é devolvida se o passo falhar ou for pulado; um passo unconfirmed não devolve. Com a quota esgotada, a execução termina failed com quota. Ela não espera a virada do mês.

Timeout, queda após iniciar o envio ou resposta ambígua ficam como unconfirmed_send. Não há reenvio automático: confira a conversa. Resposta 429 comprovada admite até cinco tentativas, com espera crescente de até 15 minutos. A mensagem enviada mantém source: automation, e os passos expõem horários de entrega e leitura.

Quando o worker encontra um bloqueio na hora do envio (canal, conexão, template, capacidade, quota, consentimento ou agendamento) ou a Meta recusa ou não confirma o envio, o dono da conta recebe um e-mail com link para o histórico no painel, no máximo um por motivo e Régua a cada dia. Paradas por resposta, saída do alvo, pausa, arquivamento ou ação manual não geram aviso.

O worker roda a cada minuto enquanto houver Régua ativa, e cada ciclo processa um número limitado de passos. Em picos, um passo pode sair alguns minutos depois do due_at.

Evento de fim

O evento automation.journey_run.finished, categoria statuses, nasce na mesma transação em que a execução chega a completed, stopped ou failed, inclusive quando ela já é criada parada. É emitido quando o contato tem número de WhatsApp. O payload traz event, customer_id, status, stop_reason, journey: { id }, run: { id, occurrence_key, opportunity_id, demand_id } e contact: { id }. Veja o envelope em Eventos de webhook.

Leia também Contatos e consentimento, Mensagens e Webhooks.