# Roles endpoints (Admin API)

> 6 FeatherPanel Admin API endpoints from admin/roles.php: methods, paths, auth, permissions, rate limits, parameters and responses.

Source: https://featherpanel.com/docs/api/reference/admin/roles/

Defined in [`backend/app/routes/admin/roles.php`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php). Authentication used here: **Admin**. Read [Authentication](https://featherpanel.com/docs/api/authentication/) for how to send credentials and [Rate limits and errors](https://featherpanel.com/docs/api/rate-limits-and-errors/) for the response envelope.

Paths, methods, permissions and rate limits come from the route file. Summaries, parameters and response codes come from the OpenAPI annotations on the controllers; endpoints without annotations show only what the route file declares.

## Endpoints

### GET `/api/admin/roles`

- Auth: Admin
- Permission: `admin.roles.view`
- Route name: `admin-roles`
- Controller: [`RolesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L26)

**Get all roles** Retrieve a paginated list of all roles with optional search functionality.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number for pagination |
| `limit` | query | integer | no | Number of records per page |
| `search` | query | string | no | Search term to filter roles by name or display name |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `roles` | Role\[\] |  |
| `pagination` | RolePagination |  |
| `search` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/roles" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Roles retrieved successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions

### GET `/api/admin/roles/{id}`

- Auth: Admin
- Permission: `admin.roles.view`
- Route name: `admin-roles-show`
- Controller: [`RolesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L35)

**Get role by ID** Retrieve a specific role by its ID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Role ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `role` | Role |  |

```bash
curl -X GET "$PANEL_URL/api/admin/roles/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Role retrieved successfully · `400` Bad request - Invalid role ID · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Role not found

### PATCH `/api/admin/roles/{id}`

- Auth: Admin
- Permission: `admin.roles.edit`
- Route name: `admin-roles-update`
- Controller: [`RolesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L49)

**Update role** Update an existing role. Only provided fields will be updated. Validates field lengths and data types.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Role ID |

Request body: [`RoleUpdate`](https://featherpanel.com/docs/api/schemas/#schema-roleupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no | Role name |
| `display_name` | string | no | Role display name |
| `color` | string | no | Role color |
| `custom_badge` | string | no | Optional short label shown on user badges |
| `badge_icon` | string | no | Optional icon or image URL shown on role badges |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `role` | Role |  |

```bash
curl -X PATCH "$PANEL_URL/api/admin/roles/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","display_name":"","color":"","custom_badge":"","badge_icon":""}'
```

Plugin events: [`featherpanel:admin:roles:role:updated`](https://featherpanel.com/docs/plugins/events/roles/#role-updated)

Responses: `200` Role updated successfully · `400` Bad request - Invalid JSON, no data provided, invalid data types, or validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Role not found · `500` Internal server error - Failed to update role

### DELETE `/api/admin/roles/{id}`

- Auth: Admin
- Permission: `admin.roles.delete`
- Route name: `admin-roles-delete`
- Controller: [`RolesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L64)

**Delete role** Permanently delete a role from the database. Default roles (Admin, Moderator, User, Banned) cannot be deleted. This action cannot be undone.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Role ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X DELETE "$PANEL_URL/api/admin/roles/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:admin:roles:role:deleted`](https://featherpanel.com/docs/plugins/events/roles/#role-deleted)

Responses: `200` Role deleted successfully · `400` Bad request - Invalid role ID or cannot delete default role · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` Role not found · `500` Internal server error - Failed to delete role

### PUT `/api/admin/roles`

- Auth: Admin
- Permission: `admin.roles.create`
- Route name: `admin-roles-create`
- Controller: [`RolesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L79)

**Create new role** Create a new role with name, display name, and color. Validates field lengths and data types.

Request body: [`RoleCreate`](https://featherpanel.com/docs/api/schemas/#schema-rolecreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | Role name |
| `display_name` | string | yes | Role display name |
| `color` | string | yes | Role color |
| `custom_badge` | string | no | Optional short label shown on user badges |
| `badge_icon` | string | no | Optional icon or image URL shown on role badges |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `role` | Role |  |

```bash
curl -X PUT "$PANEL_URL/api/admin/roles" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name":"","display_name":"","color":"","custom_badge":"","badge_icon":""}'
```

Plugin events: [`featherpanel:admin:roles:role:created`](https://featherpanel.com/docs/plugins/events/roles/#role-created)

Responses: `201` Role created successfully · `400` Bad request - Invalid JSON, missing required fields, invalid data types, or validation errors · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error - Failed to create role

### POST `/api/admin/roles/upload-badge-icon`

- Auth: Admin
- Permission: `admin.roles.edit`
- Route name: `admin-roles-upload-badge-icon`
- Controller: [`RolesController::uploadBadgeIcon`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/RolesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/roles.php#L89)

**Upload role badge icon** Upload an image to use as a custom icon on role badges.

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `icon` | string (binary) | yes | Badge icon image file |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `url` | string | Public URL of the uploaded icon |
| `filename` | string | Filename of the uploaded icon |

```bash
curl -X POST "$PANEL_URL/api/admin/roles/upload-badge-icon" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -F "icon=@./file"
```

Responses: `201` Icon uploaded successfully · `400` Bad request - No file provided, invalid file type, or file too large · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `500` Internal server error - Failed to save file
