> ## 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 cada disparo como uma ocorrência, então um disparo que não pôde acontecer na hora não se perde. Ele espera em uma lista de retidas até você executá-lo ou descartá-lo.

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 [Primeiros passos com o Flowker](/pt/reference/products/flowker/flowker-api-quick-start) para o caminho de criar e ativar.
* O binário do worker rodando com o scheduler habilitado. A variável `SCHEDULER_ENABLED` resolve para `true` a menos que você a defina como `false`, e a fila precisa de `SCHEDULER_REDIS_HOST`. Sem host, o binário do worker não sobe e nenhum workflow agendado dispara. Confira essa variável primeiro quando seus agendamentos nunca dispararem. Veja [Variáveis do scheduler](/pt/products/flowker/flowker-environment-variables#scheduler).
* 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](/pt/reference/products/flowker/get-catalog-trigger) devolve o JSON Schema do gatilho de agendamento a partir da instância em execução:

```bash theme={null}
curl -s http://localhost:4021/v1/catalog/triggers/schedule | jq -r '.schema' | jq .
```

O gatilho de agendamento é um nó com `type: "trigger"` e estes campos no seu `data`:

| 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 ou que não resolve também é avaliado como `UTC`. |
| `enabled`     | Opcional           | `false` impede o agendamento de disparar enquanto o workflow continua ativo. O padrão é `true`.                                                                                  |

<h3 id="what-the-cron-expression-accepts">
  O que a expressão cron aceita
</h3>

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](/pt/products/flowker/configuring-a-webhook-trigger).

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.

<CodeGroup>
  ```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"
    }
  }
  ```
</CodeGroup>

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

***

<Steps>
  <Step title="Salve o workflow">
    Envie o nó com o resto do seu workflow para [Criar um workflow](/pt/reference/products/flowker/create-workflow), ou para [Atualizar um workflow](/pt/reference/products/flowker/update-workflow) se o rascunho já existe. O Flowker valida o cron aqui.
  </Step>

  <Step title="Confira a cadência antes de se comprometer com ela">
    [Listar as próximas ocorrências agendadas](/pt/reference/products/flowker/list-upcoming-scheduled-occurrences) 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 "http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/upcoming?limit=3" | jq .
    ```

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

    `limit` aceita de `1` a `50` e o padrão é `10`. Um valor fora desse intervalo responde `FLK-0304`.
  </Step>

  <Step title="Ative-o">
    Chame [Ativar um workflow](/pt/reference/products/flowker/activate-workflow). O produtor restrito ao líder faz uma varredura em um intervalo padrão de 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 http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/activate | jq .
    ```
  </Step>
</Steps>

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 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`          | Outra execução deste workflow ainda estava em andamento. 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.                                                     |
| `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. Uma coisa o tempo decide: 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 as três razões acima podem fechá-lo. Então um `scheduledFor` muito no passado é normal na lista de ignoradas, e não significa que o horário disparou na hora. 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:

<Steps>
  <Step title="Liste as ocorrências retidas de um workflow">
    [Listar ocorrências agendadas retidas](/pt/reference/products/flowker/list-parked-scheduled-occurrences) devolve as mais antigas primeiro.

    ```bash theme={null}
    curl -s http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed | 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ê.
  </Step>

  <Step title="Liste as ocorrências ignoradas">
    [Listar ocorrências agendadas ignoradas](/pt/reference/products/flowker/list-skipped-scheduled-occurrences) 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 "http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/skipped?limit=10" | 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.
  </Step>

  <Step title="Conte o que está esperando em todos os workflows">
    [Contar ocorrências pendentes de revisão](/pt/reference/products/flowker/count-pending-review-occurrences) 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 http://localhost:4021/v1/workflows/schedule/pending-review-counts | 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ê.
  </Step>
</Steps>

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.

<h2 id="step-4-run-or-discard-a-parked-occurrence">
  Passo 4: Execute ou descarte uma ocorrência retida
</h2>

***

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 o mesmo 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](/pt/reference/products/flowker/list-executions) 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 três razões acima. Uma razão `active-run` significa que outra execução do workflow ainda estava em andamento. Uma razão `workflow-gone` significa que o workflow não estava ativo quando a sua execução chegou ao motor. 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.

<Steps>
  <Step title="Execute uma ocorrência">
    [Executar uma ocorrência retida](/pt/reference/products/flowker/run-parked-occurrence) 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 por padrão. A hora real de início depende da disponibilidade de workers e da capacidade da fila.

    ```bash theme={null}
    curl -s -X POST http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30/run | 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.
  </Step>

  <Step title="Descarte uma ocorrência">
    [Descartar uma ocorrência retida](/pt/reference/products/flowker/discard-parked-occurrence) a move para `discarded`, que é terminal. A ocorrência nunca executa e sai da lista de retidas.

    ```bash theme={null}
    curl -s -X POST http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/019c96a0-3f21-7b44-8d0e-5a1c7e2b9f30/discard | jq '{id, status}'
    ```

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

  <Step title="Limpe toda a lista de retidas de um workflow">
    [Descartar todas as ocorrências retidas](/pt/reference/products/flowker/discard-all-parked-occurrences) 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 http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/schedule/missed/discard-all | jq .
    ```

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

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

<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.
</Warning>

## Confirme que funcionou

***

* A cadência está saudável quando [Listar as próximas ocorrências agendadas](/pt/reference/products/flowker/list-upcoming-scheduled-occurrences) 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](/pt/reference/products/flowker/list-executions) 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](/pt/reference/products/flowker/deactivate-workflow). O Flowker para de registrar novas ocorrências para ele.
2. [Mover para rascunho](/pt/reference/products/flowker/move-workflow-to-draft).
3. [Atualizar o workflow](/pt/reference/products/flowker/update-workflow) com o novo valor de `cron`, `timezone` ou `enabled`.
4. [Ativar](/pt/reference/products/flowker/activate-workflow). O produtor restrito ao líder faz uma varredura em um intervalo padrão de 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.
</Note>

## 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-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.                                                                                                                                |

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

* **A lista de próximas mostra ocorrências, mas nada nunca roda.** A API calcula a cadência por conta própria, enquanto o binário do worker é o que dispara. Confirme que o worker roda e que você definiu `SCHEDULER_REDIS_HOST`. Veja [Variáveis do scheduler](/pt/products/flowker/flowker-environment-variables#scheduler).
* **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

***

<CardGroup cols={2}>
  <Card title="Como configurar um gatilho de webhook" icon="webhook" href="/pt/products/flowker/configuring-a-webhook-trigger">
    Comece o mesmo workflow a partir de uma chamada HTTP de entrada em vez de uma cadência.
  </Card>

  <Card title="Guia de design de workflows" icon="diagram-project" href="/pt/products/flowker/workflow-design-guide">
    Construa o resto do grafo em que o gatilho entra.
  </Card>
</CardGroup>
