> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Rodar um workflow em um agendamento

> Comece um workflow do Flowker em uma cadência, leia as ocorrências que ele planeja rodar e decida o que acontece com uma ocorrência que não pôde rodar na hora.

Um gatilho de agendamento começa um workflow em uma cadência que você escreve como uma expressão cron. O Flowker registra o próximo disparo como uma ocorrência. Uma ocorrência que não pode rodar na hora espera em uma lista de retidas até você executá-la ou descartá-la.

Use esta página para escrever o gatilho, confirmar a cadência e trabalhar a lista de retidas.

## Antes de começar

***

* Um workflow em status `draft`. Apenas um workflow em rascunho aceita uma edição, então escreva o gatilho antes de ativá-lo. Veja [Passo 4: Rode o workflow](https://docs.lerian.studio/pt/products/flowker/integration-guide.md#step-4-run-the-workflow) para o caminho de criar e ativar.
* A permissão `read` no recurso `workflows` para listar ocorrências e contagens, e `update` no mesmo recurso para executar ou descartar uma.

## Passo 1: Escreva o nó de gatilho de agendamento

***

Gatilhos já vêm prontos. Você os descobre no catálogo e nunca cria um. [Obter um gatilho do catálogo](https://docs.lerian.studio/pt/reference/products/flowker/get-catalog-trigger.md) devolve o JSON Schema do gatilho de agendamento a partir da instância em execução:

```bash theme={null}
curl -s https://your-flowker-host/v1/catalog/triggers/schedule \
  -H "Authorization: Bearer <token>" | jq -r '.schema' | jq .
```

Um workflow pode ter vários triggers de agendamento. A execução começa no trigger que disparou, e cada ocorrência carrega o `triggerNodeId` desse trigger. O trigger de agendamento é um nó com `type: "trigger"` e estes campos no `data` dele:

| Campo | Quando você define | Valor |
| - | - | - |
| `triggerType` | Sempre | `"schedule"`. |
| `cron` | Sempre | A cadência, como uma expressão cron padrão de 5 campos: `minute hour day-of-month month day-of-week`. |
| `timezone` | Opcional | O identificador IANA da zona a que os campos do cron pertencem, como `"America/Sao_Paulo"`. O padrão é `UTC`; um timezone vazio também é avaliado como `UTC`. Um nome que não é uma zona IANA falha com `FLK-0119` quando você salva ou ativa o workflow. |
| `enabled` | Opcional | `false` impede o agendamento de disparar enquanto o workflow continua ativo. O padrão é `true`. |
| `inputData` | Opcional | Um objeto que começa cada execução. O workflow o lê como `workflow.*`, do jeito que uma execução de webhook lê o corpo da requisição. |

### O que a expressão cron aceita

Cinco campos, separados por espaços. Cada campo aceita `*`, um valor, uma lista (`0,30`), um intervalo (`9-17`) ou um passo (`*/15`, `9-17/2`). O dia da semana vai de `0` a `7`, onde tanto `0` quanto `7` significam domingo. Quando você restringe o dia do mês e o dia da semana ao mesmo tempo, o agendamento dispara em um dia que combina com qualquer um dos campos. A expressão `0 9 13 * 5` dispara no dia 13 e em toda sexta-feira.

Um minuto é a cadência mais fina que uma expressão de 5 campos consegue descrever. Para algo mais rápido, receba a chamada conforme ela chega com um [gatilho de webhook](https://docs.lerian.studio/pt/products/flowker/configuring-a-webhook-trigger.md).

O Flowker confere a expressão quando você salva o workflow e de novo quando você o ativa, e responde `FLK-0117` quando ela não vale. Estas formas não valem:

* Uma expressão de seis campos, como `*/30 * * * * *`.
* Uma macro, como `@daily` ou `@every 5m`.
* Um dia ou mês por nome, como `MON`, `MON-FRI` ou `sun`.
* Um token `L` ou `#`, como `0 9 L * *` ou `0 9 * * 5#2`.
* Um valor fora do intervalo do seu campo, como `60` minutos, `24` horas, dia do mês `0` ou `32`, mês `13` ou dia da semana `8`.
* Um passo `/0`.

### Como o timezone funciona

Os campos do cron são hora de relógio na zona que você nomeia, e toda hora que a API devolve é UTC. Um agendamento `0 9 * * *` em `America/Sao_Paulo` reporta `12:00Z`. Uma zona que observa horário de verão mantém a hora de relógio ao longo da mudança: a mesma expressão em `America/New_York` reporta `14:00Z` no inverno e `13:00Z` no verão.

```json daily theme={null}
{
  "id": "trigger-1",
  "type": "trigger",
  "name": "Daily settlement",
  "position": { "x": 0, "y": 0 },
  "data": {
    "triggerType": "schedule",
    "cron": "0 9 * * *",
    "timezone": "America/Sao_Paulo"
  }
}
```

```json every 15 minutes theme={null}
{
  "id": "trigger-1",
  "type": "trigger",
  "name": "Poll for new statements",
  "position": { "x": 0, "y": 0 },
  "data": {
    "triggerType": "schedule",
    "cron": "*/15 * * * *"
  }
}
```

```json weekdays, paused theme={null}
{
  "id": "trigger-1",
  "type": "trigger",
  "name": "Weekday reconciliation",
  "position": { "x": 0, "y": 0 },
  "data": {
    "triggerType": "schedule",
    "cron": "30 7 * * 1-5",
    "timezone": "America/Sao_Paulo",
    "enabled": false
  }
}
```

```json monthly theme={null}
{
  "id": "trigger-1",
  "type": "trigger",
  "name": "Month-open batch",
  "position": { "x": 0, "y": 0 },
  "data": {
    "triggerType": "schedule",
    "cron": "0 3 1 * *",
    "timezone": "UTC"
  }
}
```

## Passo 2: Ative o workflow e leia a cadência

***

**1. Salve o workflow**

Envie o nó com o resto do seu workflow para [Criar um workflow](https://docs.lerian.studio/pt/reference/products/flowker/create-workflow.md), ou para [Atualizar um workflow](https://docs.lerian.studio/pt/reference/products/flowker/update-workflow.md) se o rascunho já existe. O Flowker valida o cron aqui.

**2. Confira a cadência antes de se comprometer com ela**

[Listar as próximas ocorrências agendadas](https://docs.lerian.studio/pt/reference/products/flowker/list-upcoming-scheduled-occurrences.md) calcula os próximos disparos direto do gatilho, então você pode lê-los enquanto o workflow ainda é um rascunho.

```bash theme={null}
curl -s "https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/upcoming?limit=3" \
  -H "Authorization: Bearer <token>" | jq .
```

```json theme={null}
{
  "occurrences": [
    { "scheduledFor": "2026-08-01T12:00:00Z", "triggerNodeId": "trigger-1" },
    { "scheduledFor": "2026-08-02T12:00:00Z", "triggerNodeId": "trigger-1" },
    { "scheduledFor": "2026-08-03T12:00:00Z", "triggerNodeId": "trigger-1" }
  ]
}
```

`limit` aceita de `1` a `50` e tem `10` como padrão. Um valor fora desse intervalo responde `FLK-0304`. Com vários triggers de agendamento, a lista combina por horário as ocorrências de todos os que estão habilitados. Ela fica vazia quando todos os triggers estão desabilitados.

**3. Ative-o**

Chame [Ativar um workflow](https://docs.lerian.studio/pt/reference/products/flowker/activate-workflow.md). O produtor restrito ao líder faz uma varredura a cada 60 segundos. Depois de uma varredura bem-sucedida, o Flowker registra e enfileira a próxima ocorrência para o horário dela.

```bash theme={null}
curl -s -X POST https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/activate \
  -H "Authorization: Bearer <token>" | jq .
```

O Flowker registra apenas o próximo disparo, nunca um calendário de disparos futuros. Quando essa ocorrência roda, o motor registra o disparo seguinte, então a cadência se carrega adiante uma ocorrência por vez.

## Passo 3: Veja quais ocorrências não rodaram

***

Uma ocorrência **fica retida** quando o motor chega a ela mais de um minuto depois do horário dela e ninguém pediu para aquele horário rodar. Causas comuns são um serviço que estava fora, uma fila que estava atrasada ou um processo que reiniciou. O Flowker nunca roda uma ocorrência retida por conta própria. Ele a segura para a sua decisão, no estado `pending-review`.

Uma ocorrência também fica retida quando a fila desiste dela antes de a execução começar. Uma execução que começa e depois falha fica registrada como falha. Uma ocorrência que fica em `running` por mais de uma hora também fica retida em `pending-review`: confira a execução dela antes de executá-la ou descartá-la. Uma ocorrência retida continua disponível para os endpoints de executar e descartar.

O Flowker nunca preenche retroativamente um horário que passou. Então a lista de retidas guarda os disparos que o Flowker já tinha registrado e não conseguiu rodar. Ela não guarda uma entrada para cada horário que passou durante uma indisponibilidade. A cadência em si retoma a partir do próximo horário futuro.

Uma ocorrência é **ignorada** quando o motor a pegou e a fechou sem rodar o workflow. O scheduler nunca roda uma ocorrência ignorada de novo. Uma ocorrência ignorada carrega um `skipReason`, e os endpoints de executar e descartar não a aceitam:

| `skipReason` | O que aconteceu |
| - | - |
| `active-run` | Uma execução deste workflow que começou no mesmo trigger ainda estava pendente, em andamento ou esperando em um nó wait. Um agendamento roda uma ocorrência por vez, então esse disparo cedeu a vez. |
| `workflow-gone` | O workflow foi apagado, ou não estava ativo quando a ocorrência chegou ao motor. |
| `trigger-gone` | O trigger de agendamento foi removido, substituído, desabilitado ou editado depois que o Flowker registrou a ocorrência. Uma edição da cadência ou uma pausa nunca dispara, portanto, a cadência antiga. |
| `execution-duplicate` | O trabalho daquele horário já tinha rodado, então o motor não o rodou duas vezes. |

As duas classes não se separam pelo tempo, com uma exceção. Um horário atrasado que você nunca pediu para rodar cai na lista de retidas, nunca na lista de ignoradas. Depois que você pede para um horário retido rodar, a idade dele para de segurá-lo. O motor então o pega como qualquer outra ocorrência, e `workflow-gone`, `trigger-gone` e `execution-duplicate` podem fechá-lo. Então um `scheduledFor` muito antigo é normal na lista de ignoradas, e isso não significa que o horário disparou a tempo. O [Passo 4](#step-4-run-or-discard-a-parked-occurrence) cobre em que a sua própria execução pode terminar.

Três leituras cobrem o quadro inteiro:

**1. Liste as ocorrências retidas de um workflow**

[Listar ocorrências agendadas retidas](https://docs.lerian.studio/pt/reference/products/flowker/list-parked-scheduled-occurrences.md) devolve as mais antigas primeiro.

```bash theme={null}
curl -s https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed \
  -H "Authorization: Bearer <token>" | jq .
```

```json theme={null}
{
  "occurrences": [
    {
      "id": "019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30",
      "workflowId": "019c96a0-0ac0-7de9-9f53-9cf842a2ee5a",
      "status": "pending-review",
      "cronExpr": "0 9 * * *",
      "timezone": "America/Sao_Paulo",
      "scheduledFor": "2026-07-29T12:00:00Z",
      "attempts": 0,
      "createdAt": "2026-07-29T11:00:04Z",
      "updatedAt": "2026-07-30T08:12:41Z"
    }
  ]
}
```

`scheduledFor` é o horário que a ocorrência representa, e `status` é o que decide se você pode agir sobre ela.

Esta rota não aceita `limit` nem cursor de página, e devolve no máximo 100 ocorrências. Planeje uma recuperação em lote em torno disso: trabalhe as linhas que você recebe, depois leia a lista de novo.

A contagem abaixo reporta o total em `pending-review`. A lista de retidas pode guardar mais linhas que essa contagem, porque ela também inclui ocorrências `missed`. O estado `missed` dura pouco: um horário atrasado o mantém enquanto o motor retém o horário como `pending-review`. Os endpoints de executar e descartar não aceitam esse estado, então leia a lista de novo e aja quando a linha mostrar `pending-review`. Descartar a lista inteira também cobre cada ocorrência pendente de revisão, não apenas as 100 que uma única leitura mostra a você.

**2. Liste as ocorrências ignoradas**

[Listar ocorrências agendadas ignoradas](https://docs.lerian.studio/pt/reference/products/flowker/list-skipped-scheduled-occurrences.md) devolve as mais antigas primeiro, cada uma com seu `skipReason`. Quando informado, `limit` aceita de `1` a `50`. Quando omitido, o padrão é `100`.

```bash theme={null}
curl -s "https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/skipped?limit=10" \
  -H "Authorization: Bearer <token>" | jq '.occurrences[] | {scheduledFor, skipReason}'
```

```json theme={null}
{ "scheduledFor": "2026-07-28T12:00:00Z", "skipReason": "active-run" }
```

Ocorrências ignoradas com `active-run` repetidas significam que o workflow demora mais que o intervalo entre dois disparos. Alargue a cadência ou faça o workflow terminar mais rápido.

**3. Conte o que está esperando em todos os workflows**

[Contar ocorrências pendentes de revisão](https://docs.lerian.studio/pt/reference/products/flowker/count-pending-review-occurrences.md) responde pelo tenant inteiro em uma chamada, que é o que você consulta para um indicador de revisão. O mapa é esparso: um workflow sem nada esperando está ausente dele.

```bash theme={null}
curl -s https://your-flowker-host/v1/workflows/schedule/pending-review-counts \
  -H "Authorization: Bearer <token>" | jq .
```

```json theme={null}
{
  "counts": {
    "019c96a0-0ac0-7de9-9f53-9cf842a2ee5a": 2
  }
}
```

Adicione `?workflowIds=<id>,<id>` para limitar as contagens aos workflows que interessam a você.

As duas listas respondem `200` com um array `occurrences` vazio para um id de workflow que seu tenant não possui, então uma lista vazia significa "nada para revisar aqui".

O Flowker expõe os dados de agendamento subjacentes por suas APIs de próximas ocorrências, de retidas e de contagem de pendentes de revisão. Consulte a documentação do Console para orientações de interface.

## Passo 4: Execute ou descarte uma ocorrência retida

***

Executar e descartar agem sobre uma ocorrência cujo `status` é `pending-review`. Qualquer outro estado responde `FLK-0755`, o que também torna uma chamada repetida segura: a segunda chamada responde um erro em vez de agir duas vezes. A sua própria execução coloca a ocorrência em um desses outros estados: ela sai de `pending-review` na hora.

Uma execução que você pede sai da lista de retidas de imediato, e a idade do horário não a segura mais. Isso não promete que o workflow roda:

* **O workflow roda.** A execução aparece em [Listar execuções](https://docs.lerian.studio/pt/reference/products/flowker/list-executions.md) para aquele workflow.
* **O motor fecha a ocorrência como ignorada.** Ela sai da lista de retidas para a lista de ignoradas com uma das razões acima. Uma execução que você pede ignora a verificação de `active-run`, então nunca fecha como `active-run`. Se outra entrega da mesma ocorrência segura o horário, a sua execução continua na fila e o Flowker a entrega de novo. Uma razão `workflow-gone` significa que o workflow não estava ativo quando a sua execução chegou ao motor. Uma razão `trigger-gone` significa que o nó de trigger de agendamento foi removido. Uma razão `execution-duplicate` significa que o trabalho daquele horário já tinha rodado.

Depois da sua execução, o scheduler nunca roda uma ocorrência ignorada de novo, e os endpoints de executar e descartar não a aceitam. Leia as duas listas antes de concluir qualquer coisa sobre um horário que você tentou recuperar. A linha ignorada pode registrar a recusa da sua recuperação, não a do disparo original.

Mantenha o workflow ativo enquanto você trabalha a lista. Uma execução recarrega o workflow, e um workflow que não está ativo fecha a ocorrência como ignorada por `workflow-gone` em vez de rodá-la.

**1. Execute uma ocorrência**

[Executar uma ocorrência retida](https://docs.lerian.studio/pt/reference/products/flowker/run-parked-occurrence.md) a move para `queued` e enfileira uma execução forçada no mesmo caminho de execução que um disparo agendado usa. O encaminhador de tarefas adiadas confere a cada segundo. A hora real de início depende da disponibilidade de workers e da capacidade da fila.

```bash theme={null}
curl -s -X POST https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30/run \
  -H "Authorization: Bearer <token>" | jq '{id, status}'
```

```json theme={null}
{ "id": "019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30", "status": "queued" }
```

A execução cobre aquele único horário. Ela não desloca a cadência: o próximo disparo continua sendo o que o motor já planejou.

**2. Descarte uma ocorrência**

[Descartar uma ocorrência retida](https://docs.lerian.studio/pt/reference/products/flowker/discard-parked-occurrence.md) a move para `discarded`, que é terminal. A ocorrência nunca executa e sai da lista de retidas.

```bash theme={null}
curl -s -X POST https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30/discard \
  -H "Authorization: Bearer <token>" | jq '{id, status}'
```

```json theme={null}
{ "id": "019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30", "status": "discarded" }
```

**3. Limpe toda a lista de retidas de um workflow**

[Descartar todas as ocorrências retidas](https://docs.lerian.studio/pt/reference/products/flowker/discard-all-parked-occurrences.md) descarta, em uma única escrita, cada ocorrência daquele workflow pendente de revisão, e reporta quantas ele moveu.

```bash theme={null}
curl -s -X POST https://your-flowker-host/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/discard-all \
  -H "Authorization: Bearer <token>" | jq .
```

```json theme={null}
{ "discarded": 7 }
```

Sem nada pendente de revisão, ele responde `200` com `"discarded": 0`, então uma chamada repetida é segura.

> [!WARNING]
>
> Um descarte não pode ser desfeito, e nunca roda nada. Leia a lista de retidas antes de limpá-la.
>
> Descartar todas as ocorrências retidas cobre exatamente as ocorrências daquele único workflow, no seu tenant, pendentes de revisão. Isso deixa o agendamento em si rodando e deixa as próximas ocorrências em paz. Não toca nas ocorrências de outro workflow, nem em ocorrências que já rodaram, falharam, foram ignoradas ou foram descartadas antes.

## Confirme que funcionou

***

* A cadência está saudável quando [Listar as próximas ocorrências agendadas](https://docs.lerian.studio/pt/reference/products/flowker/list-upcoming-scheduled-occurrences.md) devolve horários futuros e a lista de retidas continua curta.
* Uma execução funcionou quando a ocorrência saiu da lista de retidas e a execução aparece em [Listar execuções](https://docs.lerian.studio/pt/reference/products/flowker/list-executions.md) para aquele workflow.
* Um descarte funcionou quando a ocorrência saiu da lista de retidas e a contagem de pendentes de revisão daquele workflow caiu.

## Mude ou pause uma cadência

***

Apenas um workflow em rascunho aceita uma edição, então mudar a cadência são quatro chamadas:

1. [Desativar o workflow](https://docs.lerian.studio/pt/reference/products/flowker/deactivate-workflow.md). O Flowker para de registrar novas ocorrências para ele.
2. [Mover para rascunho](https://docs.lerian.studio/pt/reference/products/flowker/move-workflow-to-draft.md).
3. [Atualizar o workflow](https://docs.lerian.studio/pt/reference/products/flowker/update-workflow.md) com o novo valor de `cron`, `timezone` ou `enabled`.
4. [Ativar](https://docs.lerian.studio/pt/reference/products/flowker/activate-workflow.md). O produtor restrito ao líder faz uma varredura a cada 60 segundos. Depois de uma varredura bem-sucedida, o Flowker registra e enfileira a próxima ocorrência da nova cadência.

O Flowker não preenche retroativamente os horários que passaram enquanto o workflow estava inativo. As ocorrências retidas sobrevivem aos quatro passos. Elas continuam listadas e continuam acionáveis assim que o workflow estiver ativo de novo.

> [!NOTE]
>
> Uma ocorrência retida que o Flowker registrou antes da mudança continua pendente de revisão. Leia a lista de retidas depois de uma mudança de cadência e limpe o que você não quer mais.

## Quando algo dá errado

***

| Código | Quando acontece | O que fazer |
| - | - | - |
| `FLK-0117` | Você salva ou ativa o workflow. | O cron não é uma expressão padrão de 5 campos. Compare com [O que a expressão cron aceita](#what-the-cron-expression-accepts). |
| `FLK-0119` | Você salva ou ativa o workflow. | O `timezone` não é um nome de zona IANA. Use um identificador como `America/Sao_Paulo`. |
| `FLK-0118` | Você lista as próximas ocorrências. | O workflow não carrega gatilho de agendamento, ou o cron dele não é uma expressão que o Flowker consegue calcular. Confira o `triggerType` e o `cron` do nó de gatilho. |
| `FLK-0100` | Você lista as próximas ocorrências. | Nenhum workflow no seu tenant tem esse id. |
| `FLK-0002` | Qualquer uma dessas chamadas. | Um id de caminho não é um UUID válido. |
| `FLK-0304` | Você lista as próximas ocorrências ou as ignoradas. | `limit` está fora de `1`–`50`. |
| `FLK-0755` | Você executa ou descarta uma ocorrência. | A ocorrência não está pendente de revisão. A sua própria execução pode já tê-la movido adiante, ou ela pode ter rodado, sido ignorada ou sido descartada. Leia a lista de retidas e a lista de ignoradas antes de chamar de novo. |
| `FLK-0760` | Você executa ou descarta uma ocorrência. | Nenhuma ocorrência daquele workflow tem esse id. Pegue o id na lista de retidas do mesmo workflow. |
| `FLK-0762` | Você executa uma ocorrência. | Uma execução dessa ocorrência já está em andamento. Leia a lista de retidas e a lista de ignoradas antes de chamar de novo. |
| `FLK-0763` | Qualquer uma dessas chamadas. | O scheduler está temporariamente indisponível para o seu tenant. Listar e descartar podem continuar funcionando. Se persistir, entre em contato com o suporte da Lerian. |

Duas falhas não respondem código de erro:

* **A lista de próximas mostra ocorrências, mas nada nunca roda.** Confirme que o nó de gatilho tem `enabled` como `true` e que o workflow está ativo. Se os dois estiverem certos e nada rodar, entre em contato com o suporte da Lerian com o id do workflow.
* **O Flowker não registra nada novo para um workflow ativo.** Confira `enabled` no nó de gatilho: `false` mantém o workflow ativo e o agendamento dele quieto.

## O que vem a seguir

***

> [card] [Como configurar um gatilho de webhook](https://docs.lerian.studio/pt/products/flowker/configuring-a-webhook-trigger.md)
>
> Comece o mesmo workflow a partir de uma chamada HTTP de entrada em vez de uma cadência.

> [card] [Guia de design de workflows](https://docs.lerian.studio/pt/products/flowker/workflow-design-guide.md)
>
> Construa o resto do grafo em que o gatilho entra.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.