execution_type that controls when it runs once its step is reached. There are four models — and because runs are durable, a task can safely wait hours or days without losing progress.
Every type except
immediate requires an execution_config — omitting it is a validation error.
Immediate
The default. The task executes as soon as its step starts. You can omitexecution_type entirely.
Scheduled
Delays execution using one of threeschedule_type variants:
delay variant looks like {"schedule_type": "delay", "delay": "30m"}; a fixed variant looks like {"schedule_type": "fixed", "run_at": "2026-08-01T09:00:00Z"}.
A
cron scheduled task fires once, at the next occurrence within its execution. To run an entire definition on a repeating cadence, use a schedule instead.Windowed
Restricts execution to a recurring time window — for example, only calling prospects during business hours. The config takes atimezone, a window with allowed days plus start_time/end_time (24-hour "HH:MM"), and an outside_window policy:
The window’s clock can follow the record
timezone takes either of two forms:
A literal is checked when you save the definition: a name no runtime knows is refused with a
422 rather than surfacing hours later. An expression is not checked, because the value it produces does not exist yet.
A record whose zone will not resolve is neither failed nor quietly given the flow’s zone. If the expression resolves to nothing, or to something that is not a time-zone name, the task runs only during hours that are inside the window in every US time zone.That is a real window and the task really runs — just later in the day, because the overlap of every US zone is a few hours narrower than any one of them. Falling back to the flow’s own zone was the obvious alternative and is the wrong one: it would confidently apply a Denver window to somebody in Boston, which is exactly the mistake a per-record zone exists to prevent.
windowed when you want to confine work to particular hours; quiet hours applies regardless.
Signaled
Pauses the task until an external signal arrives — a webhook callback or a polled condition — or a timeout elapses:continue— the task resolves withon_timeout_outputand the flow proceeds; downstream expressions can branch on it (e.g., an exit condition checking{{approval.wait_for_approval.output.approved}} == false).abort_step— the task resolves with an error result, subject to itson_failurepolicy.abort_execution— the whole execution fails.
While a task is parked
Two of the four models above genuinely stop and wait: awindowed task with outside_window: schedule_next, and a signaled task waiting for its signal. While either is parked, its execution reports a distinct status rather than pretending to be busy:
That matters because these waits are long by design. Before this status existed, a task parked for two days reported
running the entire time — identical to one that was actually working — and there was no way to tell a slow run from a patient one.
Two details worth knowing:
started_atis not re-stamped on resume. A two-day wait reads as a two-day run, with the real start preserved.- The job document stays
started. Job statuses mirror only terminal execution states, and a pause is not an outcome. Read the execution to find out whether a run is parked.
execution.waiting frame on the way in and an execution.resumed frame on the way out. Neither is terminal, so a park never closes an open stream.