Schedules
A schedule is the top-level definition in Wakeplane. It combines a cadence (cron, interval, once), a target (what to run), and policies (how to behave on overlap, misfire, failure).
YAML manifest shape
Section titled “YAML manifest shape”Schedules can be created from a YAML file using wakeplane schedule create -f <file> or via POST /v1/schedules with a JSON body.
name: nightly-sync # required, unique identifier for displayenabled: true # set false to create pausedtimezone: America/Los_Angeles
schedule: kind: cron # cron | interval | once expr: "0 2 * * *" # for cron: standard 5-field cron expression
target: kind: workflow # http | shell | workflow workflow_id: sync.customers input: source: crm
policy: overlap: forbid # allow | forbid | queue_latest | replace misfire: run_once_if_late # skip | run_once_if_late | catch_up timeout_seconds: 900 max_concurrency: 1
retry: max_attempts: 5 strategy: exponential initial_delay_seconds: 30 max_delay_seconds: 900Schedule kinds
Section titled “Schedule kinds”Uses a standard 5-field cron expression (minute, hour, day-of-month, month, day-of-week). The next occurrence is computed using the schedule’s timezone.
schedule: kind: cron expr: "0 2 * * *" # 2am dailyschedule: kind: cron expr: "*/15 * * * *" # every 15 minutesinterval
Section titled “interval”Fires every N seconds. The interval is anchored to the previous next_run_at, not to wall clock time, so intervals do not drift on restart.
schedule: kind: interval every_seconds: 300 # every 5 minutesFires once at a specific time.
schedule: kind: once at: "2026-06-01T09:00:00-07:00"schedule.at is an absolute timestamp. Provide a full RFC3339 value with offset. If you want “9am Los Angeles time”, encode that offset in the timestamp itself.
After the occurrence is materialized, next_run_at becomes nil. In v0.2.x, the schedule is not automatically rewritten to enabled=false; it simply has no next occurrence left to materialize.
Timezone behavior
Section titled “Timezone behavior”Every schedule has a timezone field (IANA timezone string, e.g. America/Los_Angeles, UTC, Europe/Berlin).
- Cron expressions are evaluated in the schedule’s timezone.
- The
once.attimestamp is stored as an absolute instant; include the intended offset in the value. - Interval schedules use UTC internally; timezone affects only display.
- All
next_run_atvalues stored in the database are UTC.
DST transitions: When clocks spring forward, occurrences that fall into the gap are skipped. When clocks fall back, the nominal time fires once (not twice). This is consistent with standard cron DST handling.
Pause and resume
Section titled “Pause and resume”wakeplane schedule pause <id>wakeplane schedule resume <id>Or via HTTP:
POST /v1/schedules/{id}/pausePOST /v1/schedules/{id}/resumePause sets enabled=false and records paused_at. The planner stops materializing new occurrences. Existing pending or running runs are not affected.
Resume sets enabled=true, clears paused_at, and recomputes next_run_at from the current time. The misfire policy governs what happens to any occurrences that were due while the schedule was paused.
Trigger-now
Section titled “Trigger-now”wakeplane schedule trigger <id>Creates a manual run immediately. The normal schedule cadence is unaffected - next_run_at is not changed. The manual run has a manual:{run_id} occurrence key separate from any scheduled occurrences.
Trigger requires a reason:
# via HTTPPOST /v1/schedules/{id}/trigger{"reason": "manual smoke test"}Full replacement vs partial update
Section titled “Full replacement vs partial update”PUT /v1/schedules/{id}- full replacement. All fields required. Equivalent to delete + create.PATCH /v1/schedules/{id}- partial update. Only provided fields change. Useful for togglingenabledor updating a target URL.
Target kinds
Section titled “Target kinds”See Executors for full executor details. Brief reference:
| Kind | Required fields | Optional fields |
|---|---|---|
http | url, method | headers, body |
shell | command | args |
workflow | workflow_id | input |
Timeout and concurrency are controlled by policy.timeout_seconds and policy.max_concurrency, not by target-specific fields.
Default policy values
Section titled “Default policy values”When policy or retry fields are omitted, these defaults apply:
{ "policy": { "overlap": "forbid", "misfire": "run_once_if_late", "timeout_seconds": 300, "max_concurrency": 1 }, "retry": { "max_attempts": 0, "strategy": "exponential", "initial_delay_seconds": 30, "max_delay_seconds": 900 }}max_attempts: 0 means no retries. Set to a positive integer to enable retry behavior.
See Policies for full policy semantics.