Before you start
- A workflow in
draftstatus. Only a draft workflow accepts an edit, so write the trigger before you activate it. See Getting started with Flowker for the create-and-activate path. - The worker binary running with the scheduler enabled.
SCHEDULER_ENABLEDresolves totrueunless you set it tofalse, and the queue needsSCHEDULER_REDIS_HOST: with no host the worker binary does not start and no scheduled workflow fires. Check that variable first when your schedules never fire. See Scheduler variables. - The
readpermission on theworkflowsresource to list occurrences and counts, andupdateon the same resource to run or discard one.
Step 1: Write the schedule trigger node
Triggers are built in. You discover them in the catalog, and you never create one. Get a catalog trigger returns the schedule trigger’s JSON Schema from the running instance:
type: "trigger" and these fields in its data:
What the cron expression accepts
Five fields, separated by spaces. Each field takes*, a value, a list (0,30), a range (9-17), or a step (*/15, 9-17/2). Day-of-week runs 0–7, where both 0 and 7 mean Sunday. When you restrict day-of-month and day-of-week at the same time, the schedule fires on a day that matches either field — 0 9 13 * 5 fires on the 13th and on every Friday.
One minute is the finest cadence a 5-field expression can express. For anything faster, take the call in as it arrives with a webhook trigger.
Flowker checks the expression when you save the workflow and again when you activate it, and answers FLK-0117 when it does not hold. These forms do not hold:
- A six-field expression, such as
*/30 * * * * *. - A macro, such as
@dailyor@every 5m. - A named day or month, such as
MON,MON-FRIorsun. - An
Lor#token, such as0 9 L * *or0 9 * * 5#2. - A value outside its field’s range, such as
60minutes,24hours, day-of-month0or32, month13, or day-of-week8. - A
/0step.
How the timezone works
The cron fields are wall-clock time in the zone you name, and every time the API returns is UTC. A0 9 * * * schedule in America/Sao_Paulo reports 12:00Z. A zone that observes daylight saving keeps the wall-clock hour across the change: the same expression in America/New_York reports 14:00Z in winter and 13:00Z in summer.
Step 2: Activate the workflow and read the cadence
1
Save the workflow
Send the node with the rest of your workflow to Create a workflow, or to Update a workflow if the draft already exists. Flowker validates the cron here.
2
Check the cadence before you commit to it
List upcoming scheduled occurrences computes the next firings straight from the trigger, so you can read them while the workflow is still a draft.
limit takes 1 to 50 and defaults to 10. A value outside that range answers FLK-0304.3
Activate it
Call Activate a workflow. Within a minute the engine records the next occurrence and queues it for its slot.
Step 3: See which occurrences did not run
An occurrence parks when the engine reaches it more than a minute after its slot and nobody has asked for that slot to run: the service was down, the queue was behind, the process restarted. Flowker never runs a parked occurrence on its own — it holds it for your decision, in the
pending-review state. Parking is the one outcome that is not terminal: a parked occurrence stays actionable until you run it or discard it.
Flowker never back-fills a slot that passed. So the parked list holds the firings Flowker had already recorded and could not run — not one entry for every slot that went by during an outage — and the cadence itself resumes from the next future slot.
An occurrence is skipped when the engine took it up and closed it without running the workflow. A skipped occurrence is terminal and carries a skipReason:
The two classes do not split on timing. One thing timing does decide: a late slot you never asked to run lands in the parked list, never in the skipped list. After you ask for a parked slot to run, its age stops holding it back. The engine then takes it up like any other occurrence, and all three reasons above can close it. So a
scheduledFor far in the past is normal in the skipped list, and it does not mean the slot fired on time. Step 4 covers what your own run can end in.
Three reads cover the whole picture:
1
List the parked occurrences of one workflow
List parked scheduled occurrences returns them oldest first.
scheduledFor is the slot the occurrence stands for, and status is what decides whether you can act on it.This route takes no limit and no page cursor, and it returns at most 100 occurrences. Plan a bulk recovery around that: work the rows you get, then read the list again. The count below reports the real total. Discarding the whole list also covers every occurrence pending review, not only the 100 a single read shows you.2
List the skipped occurrences
List skipped scheduled occurrences returns them oldest first, each with its Repeated
skipReason. limit takes 1 to 50.active-run skips mean the workflow takes longer than the gap between two firings. Widen the cadence, or make the workflow finish faster.3
Count what is waiting across every workflow
Count pending-review occurrences answers for the whole tenant in one call, which is what you poll for a review badge. The map is sparse: a workflow with nothing waiting is absent from it.Add
?workflowIds=<id>,<id> to scope the counts to the workflows you care about.200 with an empty occurrences array for a workflow id your tenant does not own, so an empty list means “nothing to review here”.
Step 4: Run or discard a parked occurrence
Run and discard act on an occurrence whose
status is pending-review. Any other state answers FLK-0755, which also makes a repeated call safe: the second one is rejected instead of acting twice. Your own run puts the occurrence in one of those other states: it leaves pending-review straight away.
A run you ask for leaves the parked list at once, and the age of the slot no longer holds it back. It does not promise that the workflow runs:
- The workflow runs. The execution appears in List executions for that workflow.
- The engine closes the occurrence as skipped. It leaves the parked list for the skipped list with one of the three reasons above.
active-runmeans another run of the workflow was still going.workflow-gonemeans the workflow was not active when your run reached the engine.execution-duplicatemeans the work for that slot had already run.
FLK-0755. Read both lists before you conclude anything about a slot you tried to recover. The skipped row may record the refusal of your recovery, not of the original firing.
Keep the workflow active while you work the list. A run reloads the workflow, and a workflow that is not active closes the occurrence as a workflow-gone skip instead of running it.
1
Run one occurrence
Run a parked occurrence moves it to The run covers that one slot. It does not shift the cadence: the next firing stays the one the engine already planned.
queued and hands it to the same execution path a scheduled firing uses. It starts within a second or two.2
Discard one occurrence
Discard a parked occurrence moves it to
discarded, which is terminal. The occurrence never executes and leaves the parked list.3
Clear the whole parked list of one workflow
Discard all parked occurrences discards, in a single write, every occurrence of that workflow that is pending review, and reports how many it moved.With nothing pending review it answers
200 with "discarded": 0, so a repeat call is safe.Confirm it worked
- The cadence is healthy when List upcoming scheduled occurrences returns future slots and the parked list stays short.
- A run worked when the occurrence has left the parked list and the execution shows up in List executions for that workflow.
- A discard worked when the occurrence has left the parked list and the pending-review count for that workflow has dropped.
Change or pause a cadence
Only a draft workflow accepts an edit, so a cadence change is four calls:
- Deactivate the workflow. Flowker stops recording new occurrences for it.
- Move it to draft.
- Update the workflow with the new
cron,timezone, orenabledvalue. - Activate it. Within a minute the engine records the next occurrence from the new cadence.
An occurrence Flowker recorded before the change is still owed. Read the parked list after a cadence change, and clear anything you no longer want.
When something goes wrong
Two failures answer no error code:
- Upcoming occurrences are listed, but nothing ever runs. The API computes the cadence on its own, while the worker binary is what fires it. Confirm the worker is running and that
SCHEDULER_REDIS_HOSTis set. See Scheduler variables. - Nothing new is recorded for an active workflow. Check
enabledon the trigger node:falsekeeps the workflow active and its schedule quiet.
What’s next
Configuring a webhook trigger
Start the same workflow from an inbound HTTP call instead of a cadence.
Workflow design guide
Build the rest of the graph the trigger enters.

