Staff Privilege Groups

12 views Markdown

The six endpoints that set what staff can do in the panel.

Overview

A privilege group decides what a staff member can see and can change in the panel. Every staff member belongs to one group, and what that group carries is what they carry.

The full list of privileges that can be granted comes from an endpoint of its own. The catalogue follows the installation: modules installed add their own, and a few depend on the country.

The installation's founding group is guarded: it cannot be removed and cannot lose the right to manage privileges. That keeps anyone from leaving themselves unable to grant anything.

Reference

Reading the Privilege Catalogue

get/api/v1/admin/admins/privilege-keys
Admins/GetPrivilegeKeys admin

Returns every privilege a group can carry, gathered into groups.

Response fields data[] — 4 + meta
groupstringThe group key.
group_labelstringThe group's readable name. In the panel's current language.
singleboolWhether the group holds one privilege alone. When true the group name and the privilege name say the same thing.
permissionsobject[]The privileges in the group: each with its key and readable name.
totalintHow many groups there are. It comes back under meta.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/admins/privilege-keys' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/admins/privilege-keys', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();

const keys = data.flatMap((g) => g.permissions.map((p) => p.key));
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privilege-keys');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The catalogue follows the INSTALLATION: modules add privileges, and some depend on country.
$groups = Api::Admins()->GetPrivilegeKeys()['data'];

Listing the Groups

get/api/v1/admin/admins/privileges
Admins/GetPrivileges admin

Returns the privilege groups defined and who sits in them.

Query 3
pageintWhich page.
limitintRecords per page.
searchstringSearches the group name.
Response fields data[] — 5 + meta — 4
idintThe group id.
namestringThe group name.
permission_countintHow many privileges it carries.
appointeesobject[]The staff in this group: their ids and names.
is_rootboolWhether it is the founding group. It cannot be removed.
totalintHow many there are. It comes back under meta.
pageintThe page you are on.
limitintThe page size.
next_pageintThe next page.
Errors 1
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/admins/privileges' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch('https://panel.example.com/api/v1/admin/admins/privileges', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privileges');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The list gives the COUNT rather than the privilege NAMES; read the detail for those.
$groups = Api::Admins()->GetPrivileges()['data'];

Creating a Group

post/api/v1/admin/admins/privileges
Admins/CreatePrivilege admin

Defines a new privilege group.

Body 2
namestringreqThe group name.
permissionsstring[]The privilege keys to grant. Valid keys come from the catalogue endpoint.
Response fields 201 — data — 4
dataobjectThe group created. Same shape as the detail endpoint.
Errors 5
name_required422The group name is empty.
permissions_exceed_holder422The group would grant permissions the account behind your key does not hold. A key owned by the root privilege group is not capped.
create_failed422The group could not be created.
blocked_by_gate422A hook refused the save.
insufficient_scope403The key lacks the required scope.
Request
curl -X POST 'https://panel.example.com/api/v1/admin/admins/privileges' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"Destek Ekibi","permissions":["TICKETS"]}'
const res = await fetch('https://panel.example.com/api/v1/admin/admins/privileges', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Support Team',
    permissions: ['ADMIN_CONFIGURE', 'TICKETS'],
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privileges');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'name'        => 'Support Team',
        'permissions' => ['ADMIN_CONFIGURE', 'TICKETS'],
    ]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A group with no privileges is valid: it gets created while its members see nothing.
Api::Admins()->CreatePrivilege([
    'name'        => 'Support Team',
    'permissions' => ['TICKETS'],
]);

Reading One Group

get/api/v1/admin/admins/privileges/{pid}
Admins/GetPrivilege admin

Returns one privilege group with the privileges it carries.

Response fields data — 4
idintThe group id.
namestringThe group name.
permissionsstring[]The privilege keys in the group.
is_rootboolWhether it is the founding group.
Errors 2
not_found404No such privilege group.
insufficient_scope403The key lacks the required scope.
Request
curl 'https://panel.example.com/api/v1/admin/admins/privileges/1' \
  -H "Authorization: Bearer $API_KEY"
const res  = await fetch(`https://panel.example.com/api/v1/admin/admins/privileges/${pid}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privileges/' . $pid);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $apiKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// Read this BEFORE adding a privilege: the write call REPLACES the list rather than adding.
$g = Api::Admins()->GetPrivilege(['pid' => $pid])['data'];

Updating a Group

patch/api/v1/admin/admins/privileges/{pid}
Admins/UpdatePrivilege admin the list replaces

Changes a group's name and the privileges it carries.

Body 2
namestringThe group name.
permissionsstring[]The complete set of privileges. Your list replaces what was there.
Response fields data — 4
dataobjectThe group as it now stands. Same shape as the detail endpoint.
Errors 7
not_found404No such privilege group.
name_required422The group name is empty.
root_needs_privileges422The founding group cannot lose the privilege-management right.
permissions_exceed_holder422The group would grant permissions the account behind your key does not hold. A key owned by the root privilege group is not capped.
save_failed422The group could not be saved.
blocked_by_gate422A hook refused the save.
insufficient_scope403The key lacks the required scope.
Request
curl -X PATCH 'https://panel.example.com/api/v1/admin/admins/privileges/3' \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"permissions":["TICKETS","SERVICES"]}'
const res = await fetch(`https://panel.example.com/api/v1/admin/admins/privileges/${pid}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    permissions: ['ADMIN_CONFIGURE', 'TICKETS', 'SERVICES'],
  }),
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privileges/' . $pid);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'PATCH',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['permissions' => ['TICKETS', 'SERVICES']]),
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// To add one privilege, read the CURRENT list and append; otherwise the rest drop away.
$g = Api::Admins()->GetPrivilege(['pid' => $pid])['data'];
$g['permissions'][] = 'SERVICES';

Api::Admins()->UpdatePrivilege(['pid' => $pid, 'permissions' => $g['permissions']]);

Removing a Group

delete/api/v1/admin/admins/privileges/{pid}
Admins/DeletePrivilege admin

Removes a privilege group.

Response fields data — 2
deletedboolWhether the delete ran.
idintThe id of the group removed.
Errors 4
not_found404No such privilege group.
root_protected422The founding group cannot go.
delete_failed422The group could not be removed.
insufficient_scope403The key lacks the required scope.
Request
curl -X DELETE 'https://panel.example.com/api/v1/admin/admins/privileges/3' \
  -H "Authorization: Bearer $API_KEY"
const res = await fetch(`https://panel.example.com/api/v1/admin/admins/privileges/${pid}`, {
  method: 'DELETE',
  headers: { Authorization: `Bearer ${apiKey}` },
});

const body = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/admin/admins/privileges/' . $pid);
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);
// Move the STAFF INSIDE first: accounts bound to the group can be left without footing.
$g = current(array_filter(
    Api::Admins()->GetPrivileges()['data'], fn ($x) => $x['id'] === $pid,
));
if (! $g['appointees']) Api::Admins()->DeletePrivilege(['pid' => $pid]);

Pitfalls

The privilege list is replaced, not added to

The privilege list you send on an update replaces what was there. Sending only the new privilege to widen a group strips every other one from it, and the staff inside suddenly see next to nothing in the panel. Read the detail first and append to it.

The catalogue follows the installation

The list of privilege keys is not fixed: modules installed add their own, and a few depend on the installation's country. A script with the keys written into it tries to grant something that does not exist on another installation. Read the catalogue each time.

The founding group cannot lose privilege management

Taking the privilege-management right away from the founding group is refused. The lock is deliberate: were that right lost, no account could grant anything again and the installation would be left unmanageable. The group cannot be removed either.

Empty a group before removing it

Removing a privilege group can leave the staff bound to it without footing. The listing gives the people in each group by name, so look there and move the accounts to another group first. Removing an empty group is safe.

The listing does not name the privileges

The group listing gives the number of privileges alone and not which ones. Two groups can carry the same count and do entirely different things. To see what a group really allows, read it from the detail endpoint.

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.