Scheduler
Create and manage scheduled events, including action automations.
Scheduler API
List Events
scheduler_events:readPath, query, and header parameters
startRequiredendRequiredResponses
Events fetched in the requested range.
{
"status": "fetch",
"count": 2,
"range": {
"start": "2026-04-01T00:00:00+02:00",
"end": "2026-04-30T23:59:59+02:00"
},
"events": [
{
"id": "681f0f...",
"event_type": "appointment",
"title": "Quarterly Review",
"schedule_date": "2026-04-12T09:00:00+02:00",
"end_date": "2026-04-12T10:00:00+02:00"
}
]
}Request examples
curl --request GET 'https://api.hub.donutwork.com/2026-02-01/scheduler/events.json?start=2026-10-01&end=2026-11-01' \
--header 'Authorization: Bearer YOUR_API_KEY'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/scheduler/events.json?start=2026-10-01&end=2026-11-01', {
method: 'GET',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
},
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/scheduler/events.json?start=2026-10-01&end=2026-11-01');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
],
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Create Event
scheduler_events:writePath, query, and header parameters
No path, query, or additional header parameters.
Request Body
{
"event": {
"event_type": "action",
"title": "Run Workflow Daily",
"schedule_date": "2026-04-20T07:30:00+02:00",
"end_date": "2026-04-20T07:30:00+02:00",
"is_all_day": false,
"color": "primary",
"action_type": "workflow",
"action_details": {
"workflow_id": "67ffac1f8a3f0f2f88f9dd10",
"payload": {
"source": "api"
}
},
"recurrence": {
"type": "week",
"interval": 1,
"endDate": "2026-12-31"
}
}
}eventRequiredResponses
Event created.
{
"id": "681f0f...",
"event": {
"id": "681f0f...",
"event_type": "action",
"action_type": "workflow"
}
}Validation error on event payload.
{
"error": "Invalid \"action_type\". Allowed values: charge, job_runner, workflow"
}Request examples
curl --request POST 'https://api.hub.donutwork.com/2026-02-01/scheduler/events.json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"event": {
"event_type": "action",
"title": "Run Workflow Daily",
"schedule_date": "2026-04-20T07:30:00+02:00",
"end_date": "2026-04-20T07:30:00+02:00",
"is_all_day": false,
"color": "primary",
"action_type": "workflow",
"action_details": {
"workflow_id": "67ffac1f8a3f0f2f88f9dd10",
"payload": {
"source": "api"
}
},
"recurrence": {
"type": "week",
"interval": 1,
"endDate": "2026-12-31"
}
}
}'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/scheduler/events.json', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"event": {
"event_type": "action",
"title": "Run Workflow Daily",
"schedule_date": "2026-04-20T07:30:00+02:00",
"end_date": "2026-04-20T07:30:00+02:00",
"is_all_day": false,
"color": "primary",
"action_type": "workflow",
"action_details": {
"workflow_id": "67ffac1f8a3f0f2f88f9dd10",
"payload": {
"source": "api"
}
},
"recurrence": {
"type": "week",
"interval": 1,
"endDate": "2026-12-31"
}
}
}),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/scheduler/events.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{
"event": {
"event_type": "action",
"title": "Run Workflow Daily",
"schedule_date": "2026-04-20T07:30:00+02:00",
"end_date": "2026-04-20T07:30:00+02:00",
"is_all_day": false,
"color": "primary",
"action_type": "workflow",
"action_details": {
"workflow_id": "67ffac1f8a3f0f2f88f9dd10",
"payload": {
"source": "api"
}
},
"recurrence": {
"type": "week",
"interval": 1,
"endDate": "2026-12-31"
}
}
}',
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Update Event
scheduler_events:writePath, query, and header parameters
eventIdRequiredRequest Body
{
"event": {
"title": "Run Workflow - Updated",
"recurrence": {
"type": "month",
"interval": 1,
"endDate": "2027-04-30"
}
}
}eventRequiredResponses
Event updated.
{
"id": "681f0f...",
"event": {
"id": "681f0f...",
"title": "Run Workflow - Updated"
}
}Request examples
curl --request PUT 'https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"event": {
"title": "Run Workflow - Updated",
"recurrence": {
"type": "month",
"interval": 1,
"endDate": "2027-04-30"
}
}
}'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json', {
method: 'PUT',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"event": {
"title": "Run Workflow - Updated",
"recurrence": {
"type": "month",
"interval": 1,
"endDate": "2027-04-30"
}
}
}),
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => '{
"event": {
"title": "Run Workflow - Updated",
"recurrence": {
"type": "month",
"interval": 1,
"endDate": "2027-04-30"
}
}
}',
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.
Delete Event
scheduler_events:writePath, query, and header parameters
eventIdRequiredResponses
Event deleted.
{
"id": "681f0f...",
"deleted": true
}Request examples
curl --request DELETE 'https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json' \
--header 'Authorization: Bearer YOUR_API_KEY'const response = await fetch('https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json', {
method: 'DELETE',
headers: {
Authorization: 'Bearer ' + process.env.DONUTWORK_API_KEY,
},
});
const requestId = response.headers.get('x-request-id');
if (!response.ok) {
const error = await response.text();
throw new Error(`${response.status} ${error} [${requestId}]`);
}
const contentType = response.headers.get('content-type') ?? '';
const data = response.status === 204 ? null
: contentType.includes('application/json') ? await response.json()
: await response.text();$request = curl_init('https://api.hub.donutwork.com/2026-02-01/scheduler/events/EVENTID.json');
curl_setopt_array($request, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('DONUTWORK_API_KEY'),
],
]);
$response = curl_exec($request);
if ($response === false) {
$error = curl_error($request);
curl_close($request);
throw new RuntimeException($error);
}
$status = curl_getinfo($request, CURLINFO_RESPONSE_CODE);
$contentType = (string) curl_getinfo($request, CURLINFO_CONTENT_TYPE);
curl_close($request);
if ($status >= 400) { throw new RuntimeException($response); }
$data = $status === 204 ? null
: (str_contains($contentType, 'application/json')
? json_decode($response, true, flags: JSON_THROW_ON_ERROR) : $response);Replace uppercase placeholders and sample values with your own data and company resource IDs. Keep the API key on a trusted server. Reuse an idempotency key only for the same logical request and payload.