Health and Key Check

7 views Markdown

The two endpoints saying the API is up and what your key can do.

Overview

These two endpoints answer an integration's first two questions: is the API up and what can this key do.

The health check wants no credentials and can be called straight from a monitor or a version check. The key check wants a key while wanting no scope: every valid key may read its own permissions.

Together they make a diagnostic pair. When the health check passes and the key check fails, the trouble is with the credentials rather than the server.

Reference

The Health Check

get/api/v1/admin/ping
System/Ping no key needed

Returns that the API is up, along with the server time.

Response fields data — 3
pongboolWhether the API is up.
versionstringThe API version.
timestringThe server's time. It comes in the server's own time zone.
Errors
This endpoint is open to everyone and returns no error.
Request
curl 'https://panel.example.com/api/v1/admin/ping'
const res = await fetch('https://panel.example.com/api/v1/admin/ping');
const { data } = await res.json();

const drift = Math.abs(Date.parse(data.time) - Date.now());
$ch = curl_init('https://panel.example.com/api/v1/admin/ping');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// This endpoint WANTS NO KEY: reaching it says nothing about whether your key works.
$up = Api::System()->Ping()['data']['pong'] ?? false;

What the Key Is

get/api/v1/admin/whoami
System/Whoami no scope needed

Returns which key you are using and what it may do.

Response fields data — 4
idintThe key id.
namestringThe name the key was given.
permissionsstring[]The scopes the key carries. Group and action pairs.
last_accessstringWhen it was last used.
Errors 4
missing_token401The authorisation header was not sent.
invalid_token401The key is not valid.
ip_not_allowed403The request came from outside the addresses allowed.
rate_limited429The request limit was passed.
Request
curl 'https://panel.example.com/api/v1/admin/whoami' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch('https://panel.example.com/api/v1/admin/whoami', {
  headers: { Authorization: `Bearer ${apiKey}` },
});

if (res.status === 401) return promptForKey();

const { data } = await res.json();
const canReadInvoices = data.permissions.some((s) => s.startsWith('Invoices/'));
$ch = curl_init('https://panel.example.com/api/v1/admin/whoami');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Reading the scopes UP FRONT beats learning them from a 403 on every call.
$me = Api::System()->Whoami()['data'];
$may = fn (string $s) => in_array($s, $me['permissions'], true)
    || in_array(explode('/', $s)[0] . '/*', $me['permissions'], true);

Pitfalls

The health check does not verify your key

The health endpoint checks no credentials: it answers successfully even with a key revoked, expired or never sent. Resting a connection test on it alone reports a healthy system while the real calls fail.

The server time is not your time

The time returned sits in the server's own zone and can differ from yours. The dates on the other endpoints share that zone, so comparing one against your own clock gives results that do not line up. Take this endpoint's time as the reference.

The scope list can carry a wildcard

The permission list can hold a group wildcard or a star covering everything rather than the actions one by one. Looking for an action with a plain comparison gives a false negative on a key that carries a wildcard. Test the group wildcard as well.

The quickest way to tell an auth error apart

When a call answers 403 the cause is either a missing scope or the wrong key. The key endpoint tells the two apart in one call: with it working the key is valid and the trouble lies in the scope. A restricted address and a passed request limit show here as well.

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.