Scheduler
Manage Grav's cron-based scheduler. List registered jobs, inspect cron installation status, review execution history, and trigger manual runs. Permissions: api.scheduler.read / api.scheduler.write.
Manage Grav's cron-based scheduler. List registered jobs, inspect cron installation status, review execution history, and trigger manual runs.
Permissions: api.scheduler.read / api.scheduler.write.
List Scheduler Jobs
GET
/scheduler/jobs
List every registered scheduler job (both plugin-registered and system jobs like cache-purge, cache-clear, backups). Each job includes its cron expression, enabled flag, last-run timestamp, status, and any error from the last run. Fires `onSchedulerInitialized` so system jobs show up even if no one has touched the scheduler yet this request.
JSON
{"data": [{"id": "cache-purge", "command": "bin/grav cache --purge", "expression": "0 4 * * *", "enabled": true, "status": "success", "last_run": "2026-04-17T04:00:00+00:00", "error": null}]}
Response Codes
200
Jobs returned.
401
Unauthorized.
403
Missing `api.scheduler.read` permission.
Scheduler Status
GET
/scheduler/status
Report the scheduler's crontab installation state, the cron + scheduler commands Grav would expect, the effective user (`whoami`), health diagnostics, and whether the optional scheduler-webhook plugin is installed/enabled. Drives the "is cron set up?" panel on the Admin2 dashboard.
JSON
{"data": {"crontab_status": "installed", "cron_command": "* * * * * cd /path/to/grav && /usr/bin/php bin/grav scheduler", "scheduler_command": "bin/grav scheduler", "whoami": "www-data", "health": {}, "triggers": [], "webhook_installed": false, "webhook_enabled": false}}
Response Codes
200
Status returned.
401
Unauthorized.
403
Missing `api.scheduler.read` permission.
crontab_status is one of: not_installed, installed, error, unknown.
Job History
GET
/scheduler/history
Paginated job execution history sorted by most recent first. Each record has the job id, last status (`success`/`failure`/`pending`/`unknown`), last run ISO-8601 timestamp, and any error message captured on failure.
Parameters
| Name | Type | Description |
|---|---|---|
| page optional | integer | Page number (default 1). |
| per_page optional | integer | Items per page. |
JSON
{"data": [{"job_id": "cache-purge", "status": "success", "last_run": "2026-04-17T04:00:00+00:00", "error": null}], "meta": {"total": 12, "page": 1, "per_page": 50}}
Response Codes
200
History returned.
401
Unauthorized.
403
Missing `api.scheduler.read` permission.
Run Scheduler
POST
/scheduler/run
Manually trigger a scheduler run. When `force` is true, runs every job regardless of its cron expression; otherwise runs only jobs that are currently due. Returns a snapshot of every job's state after the run.
Parameters
| Name | Type | Description |
|---|---|---|
| force optional | boolean | If true, run all jobs now regardless of schedule. Defaults to false. |
JSON
{"force": true}
JSON
{"data": {"message": "Scheduler run completed.", "forced": true, "job_states": {"cache-purge": {"state": "success", "last-run": 1713355200}}}}
Response Codes
200
Run completed.
401
Unauthorized.
403
Missing `api.scheduler.write` permission.