# Staff Privilege Groups

https://dev.wisecp.com/es/staff-privilege-groups

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 JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/admins/privilege-keys' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
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));
```

```php
$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);
```

```php
// 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 JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/admins/privileges' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch('https://panel.example.com/api/v1/admin/admins/privileges', {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$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);
```

```php
// 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 JavaScript PHP (HTTP) PHP (Internal)

```bash
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"]}'
```

```javascript
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();
```

```php
$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);
```

```php
// 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 JavaScript PHP (HTTP) PHP (Internal)

```bash
curl 'https://panel.example.com/api/v1/admin/admins/privileges/1' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
const res  = await fetch(`https://panel.example.com/api/v1/admin/admins/privileges/${pid}`, {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const body = await res.json();
```

```php
$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);
```

```php
// 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 JavaScript PHP (HTTP) PHP (Internal)

```bash
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"]}'
```

```javascript
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();
```

```php
$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);
```

```php
// 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 JavaScript PHP (HTTP) PHP (Internal)

```bash
curl -X DELETE 'https://panel.example.com/api/v1/admin/admins/privileges/3' \
  -H "Authorization: Bearer $API_KEY"
```

```javascript
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();
```

```php
$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);
```

```php
// 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.

## Related Articles

- [Staff Accounts](https://dev.wisecp.com/en/staff-accounts)
- [Staff Departments](https://dev.wisecp.com/en/staff-departments)
- [API Credentials](https://dev.wisecp.com/en/api-credentials)
