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 caminho | Operação |
|---|---|
GET /api/v1/journeys | Listar 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/journeys | Criar 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=N | Arquivar 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}/runs | Listar execuções da Régua. |
POST /api/v1/journeys/{id}/runs | Programar 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.
| Campo | Regra | Padrão |
|---|---|---|
customer_id | Obrigatório. UUID de um Cliente da conta. | — |
name | Obrigatório, 1 a 160 caracteres. | — |
status | active 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_kind | contact, opportunity ou demand. | contact |
trigger_kind | contact_date, stage_entered, appointment ou demand_status. | contact_date |
date_field_key | Com contact_date: chave de um campo personalizado do tipo data. O valor no contato é AAAA-MM-DD. | — |
stage_id | Com stage_entered: UUID de uma etapa do Cliente. | — |
demand_status | Com demand_status: open, in_progress, waiting_customer. | — |
appointment_service_id | Com appointment, opcional: serviço da Agenda do Cliente. Ausente, vale qualquer serviço. | null |
offset_days | Com contact_date: dias antes (negativo) ou depois da data, de −3.660 a 3.660. | 0 |
offset_hours | Com appointment: horas antes (negativo) ou depois do horário, de −87.840 a 87.840. | 0 |
yearly | Com contact_date: repete a data todo ano. 29/02 cai em 28/02 em ano comum. | true |
stop_on_reply | Interrompe quando o contato responde. | true |
stop_on_exit | Interrompe quando o alvo sai da etapa ou do estado do gatilho. | true |
send_start_hour | Início da janela de envio, 0 a 23, horário de Brasília. | 9 |
send_end_hour | Fim da janela, 1 a 24, maior que o início. | 20 |
steps | Obrigatório, 1 a 50 passos, na ordem de envio. | — |
steps[].template_id | UUID de um template da conta numa conexão do mesmo Cliente e do mesmo ambiente da chave. | — |
steps[].delay_minutes | Espera 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_map | Objeto 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_kind | target_kind | Exige | Quando programa |
|---|---|---|---|
contact_date | contact | date_field_key | No 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_entered | contact, opportunity | stage_id | Quando o contato entra na etapa, ou quando uma oportunidade aberta entra nela. |
appointment | contact | appointment_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_status | demand | demand_status | Quando 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.
| Fonte | Valor |
|---|---|
contact.name | Nome de perfil do contato. |
contact.field:<chave> | Campo personalizado do contato. Booleano vira "Sim"/"Não"; campo vazio vira texto vazio. |
customer.name | Nome do Cliente dono da Régua. |
appointment.date | Data do agendamento, como 25/09/2026 (só em Réguas de agendamento). |
appointment.time | Hora do agendamento, como 14:30 (só em Réguas de agendamento). |
appointment.datetime | Data 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:
| status | Significado |
|---|---|
scheduled | Programada; nenhum passo saiu ainda. |
running | Pelo menos um passo foi reivindicado pelo worker. |
completed | Todos os passos foram enviados. |
stopped | Interrompida por regra (resposta, consentimento, saída, manual…). Veja stop_reason. |
failed | Um 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_idoudemand_id: obrigatório conforme otarget_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 com422.
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 passo | Significado |
|---|---|
pending | Aguardando. Passos depois do próximo vêm com due_at "infinity" até o anterior sair. |
sending | Reivindicado pelo worker. |
sent | Aceito pela Meta; external_id é o wamid e delivered_at/read_at chegam depois. |
skipped | Não enviado porque a execução parou; skip_reason diz por quê. |
failed | Recusa comprovada ou bloqueio antes do envio; error diz por quê. |
unconfirmed | Resposta 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ódigo | Execução | Quando |
|---|---|---|
replied | stopped | O contato respondeu e stop_on_reply está ligado. |
opted_out | stopped | O contato revogou o consentimento de marketing. Não afeta sequências só com templates UTILITY ou AUTHENTICATION. |
no_consent | stopped | Passo de marketing sem consentimento concedido. |
entity_exited | stopped | Oportunidade encerrada, demanda resolvida ou, com stop_on_exit, o alvo saiu da etapa ou do estado. |
paused | stopped | A Régua foi pausada no instante do envio. |
manual | stopped | action: stop pela API ou pelo painel. |
archived | stopped | A Régua foi arquivada. |
template_unavailable | stopped ou failed | Template não aprovado ou fora da conexão do contato. |
appointment_cancelled | stopped | Agendamento cancelado ou marcado como falta. |
appointment_completed | stopped | Comparecimento registrado. Só interrompe Réguas com offset_hours até 0, como lembretes. |
appointment_deleted | stopped | Agendamento apagado. |
appointment_unavailable | stopped | Agendamento cancelado, com falta, concluído ou de outro serviço no instante do envio. |
rescheduled | stopped | Agendamento mudou de horário ou de serviço. |
due_passed | stopped | O horário do primeiro passo já tinha passado quando o agendamento foi lido. |
channel_unavailable | stopped ou failed | Contato sem número de WhatsApp utilizável. |
not_connected | failed | Número sem conexão ativa ou sem token. |
capacity | failed | A conta do WhatsApp Business está banida ou restrita, ou não foi possível verificar. |
quota | failed | Quota mensal de templates esgotada. |
unconfirmed_send | failed | Envio iniciado sem confirmação da Meta. |
invalid_values | failed | Faltou o valor de uma variável do template (por exemplo, o contato sem nome ou sem o campo usado). |
dispatch_blocked | failed | A conversa do contato tinha outro envio em andamento ou aguardando conciliação. |
<mensagem da Meta> | failed | Recusa 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.
