Schedules API
All schedule endpoints are project-scoped. The actions are enable / disable / trigger, not pause / resume.
List schedules
Section titled “List schedules”GET /api/v1/projects/{slug}/schedulesRole: viewer.
Query params: scheduler (e.g. celery-beat, apscheduler), enabled (bool), cursor, limit.
{ "items": [ { "id": "...", "project_id": "...", "name": "email.daily-digest", "scheduler": "celery-beat", "trigger_type": "cron", "trigger": {"minute": "0", "hour": "9", "day_of_week": "*"}, "task": "email.send_daily_digest", "args": [], "kwargs": {"locale": "en-US"}, "enabled": true, "last_run_at": "...", "next_run_at": "...", "created_at": "...", "updated_at": "..." } ], "next_cursor": "..."}Get schedule
Section titled “Get schedule”GET /api/v1/projects/{slug}/schedules/{schedule_id}Role: viewer.
Create schedule
Section titled “Create schedule”POST /api/v1/projects/{slug}/schedulesRole: operator. CSRF-protected.
{ "name": "email.daily-digest", "scheduler": "celery-beat", "trigger_type": "cron", "trigger": {"minute": "0", "hour": "9", "day_of_week": "*"}, "task": "email.send_daily_digest", "args": [], "kwargs": {"locale": "en-US"}, "enabled": true}args and kwargs JSON are each capped at 64 KiB.
Update schedule
Section titled “Update schedule”PATCH /api/v1/projects/{slug}/schedules/{schedule_id}Role: operator. CSRF-protected. Any subset of the create fields.
Delete schedule
Section titled “Delete schedule”DELETE /api/v1/projects/{slug}/schedules/{schedule_id}Role: admin. CSRF-protected.
Enable / disable / trigger
Section titled “Enable / disable / trigger”POST /api/v1/projects/{slug}/schedules/{schedule_id}/enablePOST /api/v1/projects/{slug}/schedules/{schedule_id}/disablePOST /api/v1/projects/{slug}/schedules/{schedule_id}/triggerRole: operator. CSRF-protected. trigger fires the underlying task once immediately (the schedule’s cadence is untouched) and returns the schedule. Manual triggers are attributed: the resulting fire-history row carries the triggering user’s id.
Fire history
Section titled “Fire history”GET /api/v1/projects/{slug}/schedules/{schedule_id}/firesRole: viewer. Returns the schedule’s recent fires, newest first. limit defaults to 100, capped at 1000. Recorded for schedules fired by z4j-scheduler.
[ { "id": "...", "fire_id": "...", "schedule_id": "...", "command_id": "...", "status": "acked_success", "scheduled_for": "...", "fired_at": "...", "acked_at": "...", "latency_ms": 594, "error_code": null, "error_message": null, "triggered_by_user_id": null }]status is one of pending, delivered, buffered, acked_success, acked_failed, failed. triggered_by_user_id names the operator behind a manual “run now” fire; null means a scheduler-driven cadence fire. See Schedule fire history for lifecycle and retention.
Misfire history
Section titled “Misfire history”GET /api/v1/projects/{slug}/schedules/{schedule_id}/misfiresRole: viewer. Returns the schedule’s detected misfires, newest first (limit defaults to 50, capped at 1000). A misfire is a system-detected “this enabled schedule missed its slot” event, written by the brain’s misfire detector; each row carries detected_at, expected_fire_at, lateness_seconds, and the grace in force at detection time. See misfire detection.
Project-wide misfire history
Section titled “Project-wide misfire history”GET /api/v1/projects/{slug}/schedules/misfiresRole: viewer. Returns every detected misfire across ALL of the project’s schedules, newest first (limit defaults to 50, capped at 1000). Unlike the per-schedule view above, each row carries its own schedule_id so an operator can triage missed slots project-wide in one call. The z4j misfires --project <slug> CLI command is the shell-side twin of this endpoint.
Import / diff / resync
Section titled “Import / diff / resync”When the scheduler is authoritative (Celery beat, APScheduler), three colon-suffixed endpoints drive the sync workflow:
POST /api/v1/projects/{slug}/schedules:importPOST /api/v1/projects/{slug}/schedules:diffPOST /api/v1/projects/{slug}/schedules:resync:import materialises the scheduler’s current schedules into the brain. :diff reports differences without writing. :resync reconciles drift in one direction (brain to scheduler or the reverse depending on the body).