Reminders and Tasks

7 views Markdown

The ten endpoints behind personal reminders and the team's task planner.

Overview

These ten endpoints run two separate books. A reminder is personal: you leave yourself a note and it comes back at the right time. A task is shared: it is assigned to an admin, can be tied to a client and a department, and its status is followed.

The important difference is visibility. Reminders are scoped to their owner and no one else's are visible to the key; tasks are a team-wide list.

Reference

Listing the Reminders

get/api/v1/admin/tools/reminders
Tools/GetReminders admin your own records only

Returns the reminders of the admin the key belongs to.

Query parameters 3
pageintDefaults to 1.
limitintDefaults to 25, maximum 100.
searchstringSearches the records.
Response fields data[] — 7
idintId of the reminder.
notestringThe note to be reminded of.
statusstringactive or inactive.
periodstringonetime fires once, recurring repeats.
scheduled_atstring | nullWhen a one-off reminder fires.
recurringobject | nullThe pattern of a repeating reminder.
timestringWhat time of day it fires.
monthintWhich month. Minus one means every month.
dayintWhich day of the month. Minus one means every day.
created_atstring | nullWhen it was created.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tools/reminders' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tools/reminders', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/reminders');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Reminders belong to their OWNER: another admin's are not visible with this key.
$reminders = Api::Tools()->GetReminders()['data'];

Reminder Detail

get/api/v1/admin/tools/reminders/{id}
Tools/GetReminder admin

Returns one reminder. The schema is the same as a list item.

Response fields data — 7
idintId of the reminder.
notestringThe note to be reminded of.
statusstringactive or inactive.
periodstringonetime fires once, recurring repeats.
scheduled_atstring | nullWhen a one-off reminder fires.
recurringobject | nullThe pattern of a repeating reminder.
timestringWhat time of day it fires.
monthintWhich month. Minus one means every month.
dayintWhich day of the month. Minus one means every day.
created_atstring | nullWhen it was created.
Errors 3
invalid_id422The id is not valid.
not_found404No such reminder.
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tools/reminders/12' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tools/reminders/12', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/reminders/12');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Someone else's reminder answers 'not found' rather than 'not allowed'.
$response = Api::Tools()->GetReminder(['id' => 12]);

Creating a Reminder

post/api/v1/admin/tools/reminders
Tools/CreateReminder admin 201

Opens a reminder for the admin the key belongs to.

Body 7
notestringrequiredThe note to be reminded of.
statusstringactive or inactive. It defaults to active.
periodstringonetime or recurring. It defaults to one-off.
scheduled_atstringWhen it fires. Required on a one-off.
timestringThe time of day. Used on a repeating one.
monthintWhich month. Minus one means every month.
dayintWhich day. Minus one means every day.
Response fields data
dataobjectThe reminder created. Same shape as a list item.
Errors 5
note_required422The note was empty.
invalid_status422The status is neither of the two values.
invalid_period422The period is neither of the two values.
scheduled_at_required422A one-off reminder was given no time.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/tools/reminders' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"note":"Follow up with client","period":"onetime","scheduled_at":"2026-02-01 09:00:00"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/reminders', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    note: 'Follow up with client',
    period: 'onetime',
    scheduled_at: '2026-02-01 09:00:00',
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/reminders');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'note'         => 'Follow up with client',
        'period'       => 'onetime',
        'scheduled_at' => '2026-02-01 09:00:00',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// For the first of every month: day 1, month -1 (every month).
Api::Tools()->CreateReminder([
    'note'   => 'Monthly reconciliation',
    'period' => 'recurring',
    'time'   => '09:00',
    'month'  => -1,
    'day'    => 1,
]);

Updating a Reminder

patch/api/v1/admin/tools/reminders/{id}
Tools/UpdateReminder admin

Applies the fields you send and leaves the rest as they are.

Body 7
notestringrequiredThe note to be reminded of.
statusstringactive or inactive. It defaults to active.
periodstringonetime or recurring. It defaults to one-off.
scheduled_atstringWhen it fires. Required on a one-off.
timestringThe time of day. Used on a repeating one.
monthintWhich month. Minus one means every month.
dayintWhich day. Minus one means every day.
Response fields data
dataobjectThe reminder updated. Same shape as a list item.
Errors 3
not_found404No such reminder.
note_required422The note you sent was empty.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/tools/reminders/12' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"status":"inactive"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/reminders/12', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ status: 'inactive' }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/reminders/12');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['status' => 'inactive']),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Switching the status off does not DELETE it: the record stays and simply does not fire.
Api::Tools()->UpdateReminder(['id' => 12, 'status' => 'inactive']);

Deleting a Reminder

delete/api/v1/admin/tools/reminders/{id}
Tools/DeleteReminder admin

Deletes the reminder.

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

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/reminders/12');
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);
$response = Api::Tools()->DeleteReminder(['id' => 12]);

Listing the Tasks

get/api/v1/admin/tools/tasks
Tools/GetTasks admin every admin

Returns the records in the task planner. Unlike reminders, all of them are visible.

Query parameters 3
pageintDefaults to 1.
limitintDefaults to 25, maximum 100.
searchstringSearches the records.
Response fields data[] — 14
idintId of the task.
titlestringThe task title.
descriptionstringThe task description.
statusstringwaiting, inprocess, postponed or completed.
status_notestringA note on the status.
c_datestring | nullThe task date.
due_datestring | nullWhen it is due.
owner_idintId of the admin who opened it.
admin_idintId of the admin it is assigned to.
admin_namestring | nullName of the assigned admin.
user_idintId of the client it concerns.
user_namestring | nullThe client's name.
user_company_namestring | nullThe client's company name.
departmentsint[]The departments the task belongs to.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tools/tasks' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tools/tasks', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/tasks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Unlike reminders, tasks are not scoped to their owner: the list carries everyone's.
$mine = array_filter(
    Api::Tools()->GetTasks()['data'],
    fn (array $t): bool => $t['admin_id'] === $adminId,
);

Task Detail

get/api/v1/admin/tools/tasks/{id}
Tools/GetTask admin

Returns one task. The schema is the same as a list item.

Response fields data — 14
idintId of the task.
titlestringThe task title.
descriptionstringThe task description.
statusstringwaiting, inprocess, postponed or completed.
status_notestringA note on the status.
c_datestring | nullThe task date.
due_datestring | nullWhen it is due.
owner_idintId of the admin who opened it.
admin_idintId of the admin it is assigned to.
admin_namestring | nullName of the assigned admin.
user_idintId of the client it concerns.
user_namestring | nullThe client's name.
user_company_namestring | nullThe client's company name.
departmentsint[]The departments the task belongs to.
Errors 3
invalid_id422The id is not valid.
not_found404No such task.
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/tools/tasks/8' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/tools/tasks/8', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/tasks/8');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
$response = Api::Tools()->GetTask(['id' => 8]);

Creating a Task

post/api/v1/admin/tools/tasks
Tools/CreateTask admin 201

Opens a task and assigns it to an admin.

Body 10
titlestringrequiredThe task title.
c_datestringrequiredThe task date.
statusstringThe task status. It defaults to waiting.
descriptionstringThe task description.
admin_idintThe admin to assign it to. Left out, it goes to the key's owner.
user_idintThe client the task concerns.
departmentsint[]The departments to attach the task to.
due_datestringWhen it is due. Left out, today is used.
status_notestringA note to leave on the status.
notifyboolSends the assigned admin a notification.
Response fields data
dataobjectThe task created. Same shape as a list item.
Errors 4
title_required422The title was empty.
c_date_required422The date was empty.
invalid_status422The status is not one of the four values.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/tools/tasks' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"title":"Renew SSL","c_date":"2026-02-01","user_id":42,"notify":true}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/tasks', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Renew SSL',
    c_date: '2026-02-01',
    user_id: 42,
    notify: true,
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/tasks');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'title'   => 'Renew SSL',
        'c_date'  => '2026-02-01',
        'user_id' => 42,
        'notify'  => true,
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// With no assignee the task lands on the KEY'S OWNER, which matters on an integration key.
Api::Tools()->CreateTask([
    'title'    => 'Renew SSL',
    'c_date'   => '2026-02-01',
    'admin_id' => 3,
    'notify'   => true,
]);

Updating a Task

patch/api/v1/admin/tools/tasks/{id}
Tools/UpdateTask admin

Applies the fields you send; the title and the date cannot be emptied.

Body 10
titlestringrequiredThe task title.
c_datestringrequiredThe task date.
statusstringThe task status. It defaults to waiting.
descriptionstringThe task description.
admin_idintThe admin to assign it to. Left out, it goes to the key's owner.
user_idintThe client the task concerns.
departmentsint[]The departments to attach the task to.
due_datestringWhen it is due. Left out, today is used.
status_notestringA note to leave on the status.
notifyboolSends the assigned admin a notification.
Response fields data
dataobjectThe task updated. Same shape as a list item; the assignee and the client names are joined in.
Errors 5
not_found404No such task.
title_required422The title you sent was empty.
c_date_required422The date you sent was empty.
invalid_status422The status is not one of the four values.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/tools/tasks/8' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"status":"completed","status_note":"Done"}'
const res = await fetch('https://panel.example.com/api/v1/admin/tools/tasks/8', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ status: 'completed', status_note: 'Done' }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/tasks/8');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'status'      => 'completed',
        'status_note' => 'Done',
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A completed task does not LEAVE the list; filter by status on your side.
Api::Tools()->UpdateTask([
    'id'     => 8,
    'status' => 'completed',
]);

Deleting a Task

delete/api/v1/admin/tools/tasks/{id}
Tools/DeleteTask admin

Deletes the task.

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

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/tools/tasks/8');
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);
// The delete does not check ownership: you can remove another admin's task too.
Api::Tools()->DeleteTask(['id' => 8]);

Pitfalls

The two books differ in visibility

The reminder endpoints see only the records of the admin who owns the key; someone else's answers "not found". The task endpoints have no such boundary: the list carries everyone's and the delete does not check ownership. Bear in mind that an integration key can remove another admin's task.

An unassigned task lands on the key's owner

Creating a task with no assignee puts it on the key's owner. On an integration key that means piling tasks onto an account nobody actually watches. Name the assignee explicitly.

A one-off reminder needs a time

When the period is one-off the time field is required and the request is refused without it. A repeating reminder reads its pattern from the time, the month and the day instead, where minus one means "every": month minus one with day one is the first of every month.

A completed task does not leave the list

Marking a task complete does not remove it from the list; the record stays with its status. Counting open work means filtering by status on your side.

Was this helpful?

Thanks for your feedback!

Still Need Help?

Our support team is here around the clock for anything you can't find above.