Scheduled Bulk Tasks

8 Aufrufe Markdown

The six endpoints that send saved campaigns by themselves at a set time.

Overview

A scheduled task sends a saved campaign by itself at the time you set. The task holds the schedule, not the message: the text and the audience live on the template.

There are two patterns. A one-off task runs on a date and is done. A repeating one is built from a month, a day and a time. Leaving a part out means "every", so day one with no month is the first of every month.

Reference

Listing the Tasks

get/api/v1/admin/tools/bulk/scheduled-tasks
Tools/GetBulkScheduledTasks admin paged

Returns the plan for the bulk notifications that send themselves.

Query parameters 3
pageintDefaults to 1.
limitintDefaults to 25, maximum 100.
searchstringSearches the tasks.
Response fields data[] — 12
idintId of the task.
template_namestringName of the campaign it sends.
template_typestringThe channel: mail or sms.
statusstringactive is running, paused is stopped.
periodstringonetime fires once, recurring repeats.
period_datetimestring | nullWhen a one-off task fires.
period_monthint | nullThe month of a repeating task.
period_dayint | nullThe day of a repeating task.
period_hourint | nullThe hour of a repeating task.
period_minuteint | nullThe minute of a repeating task.
created_atstring | nullWhen it was created.
last_execstring | nullWhen it last ran. Empty means it never has.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// An empty last-run time says the task has NEVER run; it may be paused.
$tasks = Api::Tools()->GetBulkScheduledTasks()['data'];

$never = array_filter($tasks, fn (array $t): bool => $t['last_exec'] === null);

Creating a Task

post/api/v1/admin/tools/bulk/scheduled-tasks
Tools/CreateBulkScheduledTask admin 201

Opens a task that sends an existing campaign by itself at the time you set.

Body 6
template_idintrequiredId of the campaign to send. The campaign must not already be marked for automatic sending.
schedule_periodstringonetime or recurring. It defaults to one-off.
sending_timestringWhen to send. Required on a one-off.
period_monthintThe month of a repeating task.
period_dayintThe day of a repeating task.
period_timestringThe time of a repeating task.
Response fields data — 12
idintId of the task.
template_namestringName of the campaign it sends.
template_typestringThe channel: mail or sms.
statusstringactive is running, paused is stopped.
periodstringonetime fires once, recurring repeats.
period_datetimestring | nullWhen a one-off task fires.
period_monthint | nullThe month of a repeating task.
period_dayint | nullThe day of a repeating task.
period_hourint | nullThe hour of a repeating task.
period_minuteint | nullThe minute of a repeating task.
created_atstring | nullWhen it was created.
last_execstring | nullWhen it last ran. Empty means it never has.
Errors 4
template_required422No campaign was given.
not_found404The source campaign was not found.
schedule_required422No schedule was given.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"template_id":5,"schedule_period":"onetime","sending_time":"2026-02-15 10:00:00"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    template_id: 5,
    schedule_period: 'onetime',
    sending_time: '2026-02-15 10:00:00',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'template_id'     => 5,
        'schedule_period' => 'onetime',
        'sending_time'    => '2026-02-15 10:00:00',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The first of every month at 08:00: day 1, month left out (every month).
Api::Tools()->CreateBulkScheduledTask([
    'template_id'     => 5,
    'schedule_period' => 'recurring',
    'period_day'      => 1,
    'period_time'     => '08:00',
]);

Changing the Schedule

patch/api/v1/admin/tools/bulk/scheduled-tasks/{id}
Tools/UpdateBulkScheduledTask admin the schedule only

Changes when the task runs. The campaign itself is untouched.

Body 5
schedule_periodstringonetime or recurring. It defaults to one-off.
sending_timestringWhen to send. Required on a one-off.
period_monthintThe month of a repeating task.
period_dayintThe day of a repeating task.
period_timestringThe time of a repeating task.
Response fields data — 12
idintId of the task.
template_namestringName of the campaign it sends.
template_typestringThe channel: mail or sms.
statusstringactive is running, paused is stopped.
periodstringonetime fires once, recurring repeats.
period_datetimestring | nullWhen a one-off task fires.
period_monthint | nullThe month of a repeating task.
period_dayint | nullThe day of a repeating task.
period_hourint | nullThe hour of a repeating task.
period_minuteint | nullThe minute of a repeating task.
created_atstring | nullWhen it was created.
last_execstring | nullWhen it last ran. Empty means it never has.
Errors 3
not_found404No such scheduled task.
schedule_required422No schedule was given.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"schedule_period":"recurring","period_day":1,"period_time":"08:00"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    schedule_period: 'recurring',
    period_day: 1,
    period_time: '08:00',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'schedule_period' => 'recurring',
        'period_day'      => 1,
        'period_time'     => '08:00',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// To change the message use the template update endpoint, NOT this one.
Api::Tools()->UpdateBulkTemplate(['id' => 5, 'subject' => 'Updated']);
Api::Tools()->UpdateBulkScheduledTask(['id' => 3, 'period_time' => '09:00']);

Pausing a Task

post/api/v1/admin/tools/bulk/scheduled-tasks/{id}/pause
Tools/PauseBulkScheduledTask admin

Stops the task. The plan stops but is not deleted.

Body
No body is needed. The id in the path names the task; send an empty body.
Response fields data — 12
idintId of the task.
template_namestringName of the campaign it sends.
template_typestringThe channel: mail or sms.
statusstringactive is running, paused is stopped.
periodstringonetime fires once, recurring repeats.
period_datetimestring | nullWhen a one-off task fires.
period_monthint | nullThe month of a repeating task.
period_dayint | nullThe day of a repeating task.
period_hourint | nullThe hour of a repeating task.
period_minuteint | nullThe minute of a repeating task.
created_atstring | nullWhen it was created.
last_execstring | nullWhen it last ran. Empty means it never has.
Errors 2
not_found404No such scheduled task.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/pause' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/pause', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/pause');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Pausing does not stop notices already IN THE QUEUE: if the send started, delete them from the queue.
Api::Tools()->PauseBulkScheduledTask(['id' => 3]);

Resuming a Task

post/api/v1/admin/tools/bulk/scheduled-tasks/{id}/resume
Tools/ResumeBulkScheduledTask admin a past time is missed

Puts a paused task back into service.

Body
No body is needed. The id in the path names the task; send an empty body.
Response fields data — 12
idintId of the task.
template_namestringName of the campaign it sends.
template_typestringThe channel: mail or sms.
statusstringactive is running, paused is stopped.
periodstringonetime fires once, recurring repeats.
period_datetimestring | nullWhen a one-off task fires.
period_monthint | nullThe month of a repeating task.
period_dayint | nullThe day of a repeating task.
period_hourint | nullThe hour of a repeating task.
period_minuteint | nullThe minute of a repeating task.
created_atstring | nullWhen it was created.
last_execstring | nullWhen it last ran. Empty means it never has.
Errors 2
not_found404No such scheduled task.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/resume' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/resume', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3/resume');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A one-off whose time has passed does not run on resume: move the schedule forward first.
$task = Api::Tools()->ResumeBulkScheduledTask(['id' => 3])['data'];

if ($task['period'] === 'onetime' && $task['period_datetime'] < $now) {
    Api::Tools()->UpdateBulkScheduledTask([
        'id'           => 3,
        'sending_time' => $tomorrow,
    ]);
}

Deleting a Task

delete/api/v1/admin/tools/bulk/scheduled-tasks/{id}
Tools/DeleteBulkScheduledTask admin its records go too

Deletes the scheduled task and its run records. The campaign stays.

Response fields data — 2
deletedboolWhether the delete succeeded.
idintId of the deleted task.
Errors 2
not_found404No such scheduled task.
insufficient_scope403The key lacks the required scope.
Request
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3', {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/bulk/scheduled-tasks/3');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'DELETE',
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Deleting the task does not delete the CAMPAIGN: the template stays and can still be sent by hand.
Api::Tools()->DeleteBulkScheduledTask(['id' => 3]);

Pitfalls

A task whose time has passed does not run on resume

Pause a one-off task, resume it after its send time has passed, and it never runs. A past time does not come round again, and nothing tells you. Move the time forward first.

The task does not hold the message

These endpoints change the schedule and nothing else. Correcting the text, the subject or the audience means going to the template endpoints. A change there takes effect on the next run.

Pausing does not stop notices already sent

Pausing stops the next runs only. After a run the notices are already in the queue and keep going out. Stopping them means deleting the pending rows in the notification queue.

The campaign must not already send itself

Creating a task requires that the source campaign is not already marked for automatic sending. Otherwise the same announcement can go out by two routes at once. The campaign's state for this is on the template detail.

Leaving a part out means "every"

On a repeating task, a month or a day left out counts as every value. Giving only a time and forgetting the day sends the announcement daily. Read the task back from the list and check the pattern after creating it.

War das hilfreich?

Vielen Dank für Ihre Rückmeldung!

Brauchen Sie weitere Hilfe?

Unser Support-Team ist rund um die Uhr für Sie da, wenn Sie oben nicht fündig werden.