Skip to main content

Schedules API

Premium+ plan required

Recurring schedules are available on the Premium+ plan only. Attempting to use these endpoints on a Basic or Standard plan returns 403 PLAN_FEATURE_UNAVAILABLE. To upgrade, visit your billing settings.

Schedules let you send a notification on a repeating cadence using a standard cron expression. Each schedule references a template and one or more channels, and fires according to the cron expression evaluated in the specified IANA timezone.


POST /api/v1/schedules

Creates a new recurring schedule.

Request Body

{
"cron_expression": "0 9 * * 1",
"timezone": "America/New_York",
"template_id": "tpl_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel_ids": ["ch_11111111-2222-3333-4444-555555555555"],
"target": { "type": "all" },
"active": true
}
FieldTypeRequiredDescription
cron_expressionstringYesA valid 5-field cron expression (minute hour day-of-month month day-of-week).
timezonestringYesAn IANA timezone name (e.g. America/New_York, Europe/London, UTC).
template_idstringYesUUID of an existing notification template.
channel_idsarray of stringsYesOne or more channel UUIDs the notification will be sent through.
target.typestringYesRecipient targeting strategy. Currently supports "all" (all active subscribers).
activebooleanNoWhether the schedule should fire immediately. Defaults to true.

Response — 201 Created

{
"id": "sch_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"cron_expression": "0 9 * * 1",
"timezone": "America/New_York",
"template_id": "tpl_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel_ids": ["ch_11111111-2222-3333-4444-555555555555"],
"target": { "type": "all" },
"active": true,
"created_at": "2026-04-25T12:00:00Z",
"next_run_at": "2026-04-27T13:00:00Z"
}

Error Codes

StatusReason
401Missing or invalid bearer token.
403Your plan does not include recurring schedules (PLAN_FEATURE_UNAVAILABLE).
422cron_expression is not a valid 5-field cron string, timezone is not a recognised IANA timezone, or template_id does not refer to an existing template.

403 response body

{
"error": "PLAN_FEATURE_UNAVAILABLE",
"message": "Recurring schedules require the Premium plan."
}

GET /api/v1/schedules

Returns a paginated list of schedules for the authenticated tenant.

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number (1-based).
per_pageinteger20Number of results per page.
activebooleanOptional. When true, returns only active schedules. When false, returns only paused schedules. Omit to return all.

Response — 200 OK

{
"data": [
{
"id": "sch_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"cron_expression": "0 9 * * 1",
"timezone": "America/New_York",
"template_id": "tpl_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel_ids": ["ch_11111111-2222-3333-4444-555555555555"],
"target": { "type": "all" },
"active": true,
"created_at": "2026-04-25T12:00:00Z",
"next_run_at": "2026-04-27T13:00:00Z"
}
],
"total": 4,
"page": 1
}

GET /api/v1/schedules/:id

Retrieves a single schedule by its UUID.

Response — 200 OK

{
"id": "sch_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"cron_expression": "0 9 * * 1",
"timezone": "America/New_York",
"template_id": "tpl_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel_ids": ["ch_11111111-2222-3333-4444-555555555555"],
"target": { "type": "all" },
"active": true,
"created_at": "2026-04-25T12:00:00Z",
"next_run_at": "2026-04-27T13:00:00Z"
}

Error Codes

StatusReason
401Missing or invalid bearer token.
404No schedule found with that ID, or it belongs to a different tenant.

PATCH /api/v1/schedules/:id

Partially updates an existing schedule. All fields are optional; only the fields you supply are updated. Omitted fields retain their current values.

Request Body

{
"cron_expression": "0 */6 * * *",
"timezone": "UTC",
"template_id": "tpl_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"channel_ids": ["ch_11111111-2222-3333-4444-555555555555"],
"active": false
}
FieldTypeRequiredDescription
cron_expressionstringNoReplacement cron expression.
timezonestringNoReplacement IANA timezone.
template_idstringNoReplacement template UUID.
channel_idsarray of stringsNoReplacement list of channel UUIDs. Replaces the entire array, not merged.
activebooleanNoSet to false to pause the schedule; true to resume.

Response — 200 OK

Returns the full updated schedule object (same shape as GET /api/v1/schedules/:id).

Error Codes

StatusReason
401Missing or invalid bearer token.
403Plan downgrade detected; recurring schedules are not available on the current plan (PLAN_FEATURE_UNAVAILABLE).
404Schedule not found or cross-tenant access attempted.
422cron_expression is invalid or timezone is not a recognised IANA timezone.

DELETE /api/v1/schedules/:id

Permanently deletes a schedule. The schedule will not fire again after deletion.

warning

Deletion is irreversible. If you only want to stop the schedule temporarily, set active: false via PATCH /api/v1/schedules/:id instead.

Response — 204 No Content

An empty body is returned on success.

Error Codes

StatusReason
401Missing or invalid bearer token.
404Schedule not found or cross-tenant access attempted.

Cron Expression Reference

Schedules use the standard 5-field cron format:

┌───────────── minute (0–59)
│ ┌───────────── hour (0–23)
│ │ ┌───────────── day of month (1–31)
│ │ │ ┌───────────── month (1–12)
│ │ │ │ ┌───────────── day of week (0–7, Sunday = 0 or 7)
│ │ │ │ │
* * * * *
ExpressionMeaning
0 9 * * 1Every Monday at 9:00 AM
0 */6 * * *Every 6 hours
30 8 1 * *1st of every month at 8:30 AM
0 12 * * 1-5Weekdays at noon
0 0 * * *Daily at midnight

All times are evaluated in the timezone you specify on the schedule. See the Recurring Notifications guide for timezone best practices and DST considerations.