Function Schedulers API
Manage scheduled invocations that run a function on a recurring cron schedule.
Function schedulers are managed below a function:
GET /projects/:id/functions/:functionId/schedulersPOST /projects/:id/functions/:functionId/schedulersGET /projects/:id/functions/:functionId/schedulers/:schedulerIdPATCH /projects/:id/functions/:functionId/schedulers/:schedulerIdDELETE /projects/:id/functions/:functionId/schedulers/:schedulerId
Durable functions take schedulers on the same
routes below /projects/:id/durable-functions/:functionId, and a tick starts an
execution instead of invoking the function.
GET /projects/:id/schedulers lists every scheduler in the project, both kinds
together. Each one carries function_kind, which is standard or durable, and
tells you which collection to read the function back from.
Pass function_kind to list one kind only. Pagination totals and cursors follow
the filter, and a cursor from one kind is rejected for the other:
curl "$VOLCANO_API_URL/projects/$PROJECT_ID/schedulers?function_kind=durable&limit=20" \
-H "Authorization: Bearer $VOLCANO_TOKEN"{
"data": [
{
"id": "2c9d1e0f-3a4b-4c5d-8e9f-0a1b2c3d4e5f",
"function_id": "6f1c0f6e-6b0e-4a1d-9f8a-2c3d4e5f6a7b",
"function_kind": "durable",
"name": "nightly-reconcile",
"enabled": true,
"cron_expression": "0 3 * * *"
}
],
"limit": 20,
"total": 1,
"has_more": false
}Any value other than standard or durable answers 400.
Create request:
{
"name": "refresh-cache",
"enabled": true,
"schedule": {
"kind": "cron",
"cron_expression": "*/5 * * * *"
},
"payload": {
"source": "scheduled"
},
"regions": ["us-east-1"]
}regions is optional. If omitted, Volcano randomly chooses one deployed region and invokes the function in that region according to the cron schedule. The chosen region remains stable while it is still deployed; if geofencing removes it, Volcano randomly chooses one of the remaining deployed regions. Explicit regions must contain exactly one deployed region. Function schedulers never fan out to every deployed region; the per-region coverage Volcano runs to keep runtimes ready is its own and is not a scheduler.
schedule.cron_expression must be a standard 5-field cron expression evaluated in UTC. Seconds fields, descriptors such as @daily, and Quartz-only syntax such as ?, L, W, or # are not supported. Volcano validates that the schedule runs no more frequently than once per minute and at least once every 31 days.
At runtime, the function receives the configured payload as its event. Volcano adds __volcano_schedule metadata to the event with scheduler/run identifiers and the region that performed the invocation.
Health
Every scheduler response reports how its recent runs went:
{
"id": "2c9d1e0f-3a4b-4c5d-8e9f-0a1b2c3d4e5f",
"name": "hourly-sync",
"enabled": true,
"run_count": 52,
"health": "failing",
"consecutive_failures": 49,
"last_run_status": "failed",
"last_error": "TypeError: Cannot read properties of undefined (reading 'rows')",
"last_success_at": "2026-10-17T13:00:05Z",
"last_failure_at": "2026-10-19T14:00:04Z"
}| Field | Description |
|---|---|
health | failing while consecutive_failures is above 0, otherwise healthy, including before the first run. |
consecutive_failures | Runs failed in a row. Resets to 0 when a run succeeds. |
last_run_status | succeeded or failed. Absent before the first finished run. |
last_error | What the most recent counted failed run reported. Cleared when a run succeeds. A failure that does not count, such as a tick Volcano is still retrying in its first 15 minutes, leaves this and health unchanged and is not reported on the scheduler. |
last_success_at, last_failure_at | When the most recent run of each outcome finished. Absent until there is one. |
A durable function's run finishes when the execution it started does, so its health follows the execution's outcome: failed, timed out, or stopped counts as a failure. A standard function's run fails only when Volcano cannot invoke it; an error the handler returns does not count. A disabled scheduler keeps the health it had, apart from durable runs already started: they still count when their executions finish, and can still send an alert.
health and consecutive_failures describe the region the scheduler runs in
now. last_run_status and last_error describe the last run to finish in any
region. After you move a scheduler to another region, they can disagree until
it first runs there: a failed run in the old region is still the last run, but
the new region starts healthy.
To be told when a scheduler starts failing rather than polling for it, see Notifications.