> ## Documentation Index
> Fetch the complete documentation index at: https://theteam-13fc7f49.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Roles API Endpoints

##### *General - Roles API Documentation and Postman Guide.*

This document is based on the current Laravel source code in:

```text theme={null}
.
├── routes/
│   └── api.php
├── app/
│   ├── Http/
│   │   └── Controllers/
│   │       └── RolesController.php
│   ├── Models/
│   │   ├── Role.php
│   │   ├── Permission.php
│   │   └── PermissionRole.php
│   └── Policies/
│       └── RolePolicy.php
└── database/
    └── seeders/
        └── DatabaseSeeder.php
```

The Roles API in this project is intentionally small:

* list roles
* show a role
* update a role label/description
* assign permissions to a role for a specific company

There is currently no exposed API route to create or delete roles.

***

## Table of Contents

1. **Base URL and Auth**
2. **Seeded Roles**
3. **How Role Permissions Work in This Project**
4. **Authorization Notes**
5. **Common Permission IDs Related to Roles and Users**
6. **Endpoints**
   * **6.1 List Roles**
   * **6.2 Show Role**
   * **6.3 Update Role**
   * **6.4 Assign Permissions to a Role**
7. **Postman Examples**
   * **7.1 Fetch All Roles for Company 1**
   * **7.2 Fetch Instructor Role**
   * **7.3 Update Instructor Role Description**
   * **7.4 Give Instructor Role a Minimal User-Management Set**
8. **Known Implementation Notes**
   * **8.1 Roles Are Seeded, Not Created by API**
   * **8.2 Company Context Matters**
   * **8.3 Use Admin or Super-Admin for Testing**
   * **8.4 Permission Assignment Is a Sync Operation**
9. **Recommended Postman Test Order**

***

## 1. Base URL and Auth

Base API URL:

```json theme={null}
{{base_url}}/api
```

Recommended Postman variables:

* `{{base_url}}` = [http://127.0.0.1:8000](http://127.0.0.1:8000)
* `{{token}}` = your\_sanctum\_token

Required headers for protected endpoints:

```json theme={null}
Accept: application/json
Content-Type: application/json
Authorization: Bearer {{token}}
```

All documented role endpoints are inside the authenticated company-protected route group.

## 2. Seeded Roles

These roles are inserted by DatabaseSeeder.php:

| id | label | internal constant |
| :- | :- | :- |
| 1 | User | Role::STUDENT |
| 2 | Instructor | Role::INSTRUCTOR |
| 3 | Content Manager | Role::CONTENT\_MANAGER |
| 4 | Admin | Role::ADMIN |
| 5 | Super-Admin | Role::SUPER\_ADMIN |

Important note:

* role labels are seeded once
* you can update them through the API
* users reference roles through users.role\_id

## 3. How Role Permissions Work in This Project

The relationship is:

```text theme={null}
roles <-> permission_role <-> permissions
```

The pivot table stores:

* role\_id
* permission\_id
* company\_id

That means permissions are company-specific.

Practical meaning:

* the same role can return different permissions depending on the company\_id
* when you list or show roles, you should send company\_id
* role permissions are filtered using `wherePivot('company_id', request('company_id'))`

## 4. Authorization Notes

According to RolePolicy.php:

* `viewAny` is allowed for super-admin, admin, or users with the `roles-viewAny` permission
* `view` is allowed for super-admin, admin, or users with `roles-view` only when `user.role_id === role.id`
* `update` is allowed for super-admin, admin, or users with `roles-edit` only when `user.role_id === role.id`
* `assign_permissions` is restricted to admin and super-admin

Practical testing advice:

* use an Admin or Super-Admin token in Postman for the role endpoints

## 5. Common Permission IDs Related to Roles and Users

Useful permission IDs from `App\Models\Permission`:

| id | label |
| :- | :- |
| 11 | roles-viewAny |
| 12 | roles-view |
| 13 | roles-edit |
| 51 | users-viewAny |
| 52 | users-create |
| 53 | users-view |
| 54 | users-edit |
| 55 | users-archive |
| 56 | users-unarchive |
| 57 | users-delete |
| 58 | users-restore |
| 59 | users-force-delete |
| 130 | certifications-config-get |
| 131 | certifications-config-set |
| 133 | instructor-dashboard-access |

If you need the complete permission catalog, use the permissions endpoints or inspect `app/Models/Permission.php`.

## 6. Endpoints

### 6.1 List Roles

Returns all roles with permissions filtered for the specified company.

| Field | Value |
| :- | :- |
| Method | GET |
| URL | /api/roles |
| Auth | Bearer Token |

**Query Parameters**

| Name | Type | Required | Notes |
| :- | :- | :- | :- |
| company\_id | integer | Yes | must exist in companies |

**Example Request**

```json theme={null}
GET /api/roles?company_id=1
Authorization: Bearer {{token}}
Accept: application/json
```

**Success Response**

```json theme={null}
{
  "roles": [
    {
      "id": 1,
      "label": "User",
      "description": null,
      "permissions": [
        {
          "id": 31,
          "label": "categories-viewAny",
          "description": null,
          "pivot": {
            "role_id": 1,
            "permission_id": 31,
            "company_id": 1
          }
        },
        {
          "id": 33,
          "label": "categories-view",
          "description": null,
          "pivot": {
            "role_id": 1,
            "permission_id": 33,
            "company_id": 1
          }
        }
      ]
    },
    {
      "id": 2,
      "label": "Instructor",
      "description": null,
      "permissions": [
        {
          "id": 61,
          "label": "trainings-viewAny",
          "description": null,
          "pivot": {
            "role_id": 2,
            "permission_id": 61,
            "company_id": 1
          }
        },
        {
          "id": 133,
          "label": "instructor-dashboard-access",
          "description": null,
          "pivot": {
            "role_id": 2,
            "permission_id": 133,
            "company_id": 1
          }
        }
      ]
    }
  ]
}
```

Notes:

* the controller validates `company_id`
* permissions are returned only for the requested company

### 6.2 Show Role

Returns one role with permissions filtered by `company_id`.

| Field | Value |
| :- | :- |
| Method | GET |
| URL | /api/role/ {id} |
| Auth | Bearer Token |

**Recommended Query Parameter**

| Name | Required in practice | Notes |
| :- | :- | :- |
| company\_id | Yes | the controller filters permissions with it |

**Example Request**

```json theme={null}
GET /api/role/2?company_id=1
Authorization: Bearer {{token}}
Accept: application/json
```

**Success Response**

```json theme={null}
{
  "role": {
    "id": 2,
    "label": "Instructor",
    "description": null,
    "permissions": [
      {
        "id": 61,
        "label": "trainings-viewAny",
        "description": null,
        "pivot": {
          "role_id": 2,
          "permission_id": 61,
          "company_id": 1
        }
      },
      {
        "id": 133,
        "label": "instructor-dashboard-access",
        "description": null,
        "pivot": {
          "role_id": 2,
          "permission_id": 133,
          "company_id": 1
        }
      }
    ]
  }
}
```

Important note:

* unlike the index endpoint, `show()` does not explicitly validate `company_id`
* but you should still send it, otherwise permissions may come back empty

### 6.3 Update Role

Updates the role label and description. This endpoint uses POST, not PUT.

| Field | Value |
| :- | :- |
| Method | POST |
| URL | /api/role/ {id} |
| Auth | Bearer Token |

**Request JSON**

```json theme={null}
{
  "label": "Instructor",
  "description": "Can manage own trainings, quizzes, exams, and instructor dashboard."
}
```

**Success Response**

```json theme={null}
{
  "message": "Role updated successfully."
}
```

**Validation Error Example**

```json theme={null}
{
  "message": "The given data was invalid.",
  "errors": {
    "description": [
      "The description field is required."
    ]
  }
}
```

Notes:

* `label` is required
* `description` is also required by the controller, even though the database column itself is nullable

### 6.4 Assign Permissions to a Role

Replaces the role's permission set using `syncWithPivotValues()`.

| Field | Value |
| :- | :- |
| Method | POST |
| URL | /api/role/ {id} /assign\_permissions |
| Auth | Bearer Token |

**Request JSON**

```json theme={null}
{
  "company_id": 1,
  "permissions": [11, 12, 13, 51, 53, 54, 55, 56, 57, 58]
}
```

**Success Response**

```json theme={null}
{
  "message": "Permissions assigned successfully."
}
```

**Validation Error Example**

```json theme={null}
{
  "message": "The given data was invalid.",
  "errors": {
    "permissions.0": [
      "The selected permissions.0 is invalid."
    ]
  }
}
```

Important behavior:

* treat this endpoint as a full replace, not an incremental add
* send the full final list of permission IDs you want for that role/company
* if you send only one new permission, the others can be removed by sync behavior

## 7. Postman Examples

### 7.1 Fetch All Roles for Company 1

```json theme={null}
GET {{base_url}}/api/roles?company_id=1
Authorization: Bearer {{token}}
Accept: application/json
```

### 7.2 Fetch Instructor Role

```json theme={null}
GET {{base_url}}/api/role/2?company_id=1
Authorization: Bearer {{token}}
Accept: application/json
```

### 7.3 Update Instructor Role Description

```json theme={null}
POST {{base_url}}/api/role/2
Authorization: Bearer {{token}}
Content-Type: application/json
Accept: application/json

{
  "label": "Instructor",
  "description": "Can manage own trainings and exams and access instructor statistics."
}
```

### 7.4 Give Instructor Role a Minimal User-Management Set

```json theme={null}
POST {{base_url}}/api/role/2/assign_permissions
Authorization: Bearer {{token}}
Content-Type: application/json
Accept: application/json

{
  "company_id": 1,
  "permissions": [51, 53, 54]
}
```

## 8. Known Implementation Notes

### 8.1 Roles Are Seeded, Not Created by API

Current routes only support:

* list
* show
* update
* assign permissions

There is no exposed route for:

* create role
* archive role
* unarchive role
* delete role

### 8.2 Company Context Matters

The same role object can show different permissions depending on `company_id`.

Always send:

```json theme={null}
company_id=your_company_id
```

when reading role permissions.

### 8.3 Use Admin or Super-Admin for Testing

Because of the current policies, the safest Postman user for roles testing is:

* Admin
* or Super-Admin

### 8.4 Permission Assignment Is a Sync Operation

`assign_permissions()` uses:

```php theme={null}
$role->permissions()->syncWithPivotValues(...)
```

So the request should contain the full target permission set, not only the delta.

## 9. Recommended Postman Test Order

1. Login as an admin or super-admin
2. Call `GET /api/roles?company_id=1`
3. Call `GET /api/role/2?company_id=1`
4. Update a role description with `POST /api/role/{id}`
5. Assign a complete permission list with `POST /api/role/{id}/assign_permissions`
6. Re-fetch the role to confirm the permission pivot rows for that company


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.