Activity Logs
The eleven endpoints that read and clear sent messages, sign-ins, actions and module exchanges.
Overview
These eleven endpoints read and clear the books of what the system did: e-mails and messages sent, sign-ins, user actions, what modules exchanged with providers, and database queries.
E-mail and message bodies are stored encrypted and do not come back in the list; a separate endpoint decodes them. The other books read plainly.
Every clear shares one shape: you give a cut-off date and everything on and before it goes. The one exception is the query log, which is file-based and takes no date.
Reference
Listing the E-mail Log
Returns the record of e-mails sent. The body is not in the list.
YYYY-MM-DD HH:MM:SS. The body field is not among these; the list stays light because bodies are large.curl -G 'https://panel.example.com/api/v1/admin/tools/logs/mail' \
-H "Authorization: Bearer $API_KEY" \
-d limit=50const url = new URL('https://panel.example.com/api/v1/admin/tools/logs/mail');
url.searchParams.set('limit', '50');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/tools/logs/mail?' . http_build_query(['limit' => 50]);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The body is stored encrypted and is NOT in the list; you get it from the decode endpoint.
$logs = Api::Tools()->GetMailLogs([], ['limit' => 50])['data'];
$content = Api::Tools()->GetLogPreview(['type' => 'mail', 'id' => $logs[0]['id']]);Clearing the E-mail Log
Deletes e-mail records older than the date you give.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/logs/mail' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"before":"2026-01-01"}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/mail', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ before: '2026-01-01' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/mail');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['before' => '2026-01-01']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The response does not say HOW MANY were deleted; count them by listing first.
Api::Tools()->ClearMailLogs(['before' => '2026-01-01']);Listing the SMS Log
Returns the record of text messages sent. The body is not in the list.
admin or client.YYYY-MM-DD HH:MM:SS. The body field is missing here for the same reason as the e-mail log.curl 'https://panel.example.com/api/v1/admin/tools/logs/sms' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/sms', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/sms');
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()->GetSmsLogs();Clearing the SMS Log
Deletes text message records older than the date you give.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/logs/sms' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"before":"2026-01-01"}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/sms', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ before: '2026-01-01' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/sms');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['before' => '2026-01-01']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);Api::Tools()->ClearSmsLogs(['before' => '2026-01-01']);Listing the Sign-in Log
Returns the record of sign-ins to the panel and the client area.
client or admin. It defaults to client; staff sign-ins are the admin side and have to be asked for by that name.YYYY-MM-DD HH:MM:SS. The type filter works on the joined account, so a record always belongs to one side or the other.curl -G 'https://panel.example.com/api/v1/admin/tools/logs/login' \
-H "Authorization: Bearer $API_KEY" \
-d type=adminconst url = new URL('https://panel.example.com/api/v1/admin/tools/logs/login');
url.searchParams.set('type', 'admin');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/tools/logs/login?' . http_build_query(['type' => 'admin']);
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Without a type you get CLIENT sign-ins; staff sign-ins answer to 'admin', not 'staff'.
$staff = Api::Tools()->GetLoginLogs([], ['type' => 'admin']);Listing the Action Log
Returns the record of what users and the system did.
update, deletion, create and the like.YYYY-MM-DD HH:MM:SS. Module records share this table but stay out of this listing; they have their own endpoint.curl -G 'https://panel.example.com/api/v1/admin/tools/logs/actions' \
-H "Authorization: Bearer $API_KEY" \
-d type=adminconst url = new URL('https://panel.example.com/api/v1/admin/tools/logs/actions');
url.searchParams.set('type', 'admin');
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$url = 'https://panel.example.com/api/v1/admin/tools/logs/actions?' . http_build_query(['type' => 'admin']);
$ch = curl_init($url);
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()->GetActionLogs([], ['type' => 'admin']);Clearing the Action Log
Deletes action records older than the date you give. It leaves the module log alone.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/logs/actions' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"before":"2026-01-01"}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/actions', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ before: '2026-01-01' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/actions');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['before' => '2026-01-01']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// This clear does NOT sweep the module log; that has its own endpoint.
Api::Tools()->ClearActionLogs(['before' => '2026-01-01']);
Api::Tools()->ClearModuleLogs(['before' => '2026-01-01']);Listing the Module Log
Returns the record of what modules exchanged with providers.
module-log on this endpoint.YYYY-MM-DD HH:MM:SS. These records share a table with the action log, but clearing one leaves the other untouched.curl 'https://panel.example.com/api/v1/admin/tools/logs/module' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/module', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/module');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The module log only fills while it is ON in the log settings; an empty list is not 'all fine'.
$settings = Api::Tools()->GetLogSettings()['data'];
if ($settings['module_log']) {
$logs = Api::Tools()->GetModuleLogs();
}Clearing the Module Log
Deletes module records older than the date you give.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/logs/module' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"before":"2026-01-01"}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/module', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ before: '2026-01-01' }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/module');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['before' => '2026-01-01']),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);Api::Tools()->ClearModuleLogs(['before' => '2026-01-01']);Decoding the Body
Decrypts and returns the stored body of one e-mail or text message record.
mail or sms.curl -X POST 'https://panel.example.com/api/v1/admin/tools/logs/preview' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{"type":"mail","id":1240}'const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/preview', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ type: 'mail', id: 1240 }),
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/preview');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['type' => 'mail', 'id' => 1240]),
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The decrypted body carries client data: do not write it to your own logs.
$content = Api::Tools()->GetLogPreview([
'type' => 'mail',
'id' => 1240,
])['data']['content'];Deleting the Query Log
Deletes the database query log files. It takes no date and removes all of them.
curl -X DELETE 'https://panel.example.com/api/v1/admin/tools/logs/query' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/tools/logs/query', {
method: 'DELETE',
headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/tools/logs/query');
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);// This endpoint takes NO date: every file goes. Writing them is switched off in the settings.
Api::Tools()->ClearQueryLogs();
Api::Tools()->SetLogSettings(['query_logging' => 0]);Pitfalls
The content of e-mail and message records is stored encrypted and never comes back from the listing endpoints. Seeing what was sent means calling the decode endpoint separately, one request per record. The decrypted text carries client data, so do not store it on your side.
The module and query logs only fill while they are on in the log settings. With them off the lists come back empty, which does not mean nothing happened. Confirm in the settings that the log you need is on before investigating anything.
On the sign-in and action logs, leaving the type out gives you the client side. Looking for admin sign-ins or the system's own actions means sending the type explicitly, or you conclude the record you want never existed.
Clearing the action log leaves the module log where it is; they are separate endpoints. Making one call to free space, you may not notice the bigger book is still sitting there.
The date-based clears return only that they ran and which date they used; they give no count. To measure the effect, list the same range and count it first.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.