# TTSCM API Routes Documentation This document provides a comprehensive overview of all API routes available in the TTSCM API. ## Base URL ``` http://localhost:3000/v1 ``` --- ## Authentication Routes ### Get Authentication URI **GET** `/auth/uri` Get the Microsoft OAuth authentication URI for user login. **Authentication Required:** No **Response:** ```json { "status": 200, "message": "Successfully fetch Auth URI", "data": { "uri": "https://login.microsoftonline.com/...", "callbackKey": "ck123..." }, "successful": true } ``` --- ### OAuth Redirect Handler **GET** `/auth/redirect` Handles the OAuth redirect callback from Microsoft. This endpoint processes the authorization code and creates a user session. **Authentication Required:** No **Query Parameters:** - `code` - Authorization code from Microsoft - `state` - Callback key for WebSocket notification **Response:** Closes the browser window and emits authentication tokens via WebSocket. --- ### Refresh Access Token **POST** `/auth/refresh` Refresh an expired access token using a valid refresh token. **Authentication Required:** Yes (Refresh Token) **Headers:** - `x-refresh-token` - The refresh token **Response:** ```json { "status": 201, "message": "Token refreshed successfully!", "data": { "accessToken": "eyJhbGc...", "refreshToken": "eyJhbGc..." }, "successful": true } ``` --- ## User Routes ### Get Current User **GET** `/user/@me` Fetch the currently authenticated user's information. **Authentication Required:** Yes **Required Scopes:** `user.read` **Response:** ```json { "status": 200, "message": "Fetched user.", "data": { "id": "ckx...", "name": "John Doe", "email": "john.doe@example.com", "login": "john.doe", "image": "https://...", "roles": ["admin"], "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-02-14T00:00:00.000Z" }, "successful": true } ``` --- ### Update Current User **PATCH** `/user/@me` Update the currently authenticated user's information. **Authentication Required:** Yes **Required Scopes:** `user.write` **Request Body:** ```json { "name": "Jane Doe", "image": "https://example.com/avatar.jpg" } ``` **Response:** ```json { "status": 200, "message": "Successfully updated user.", "data": { "id": "ckx...", "name": "Jane Doe", "email": "jane.doe@example.com", "image": "https://example.com/avatar.jpg" }, "successful": true } ``` --- ### Check User Permissions **POST** `/user/@me/check-permission` Check if the currently authenticated user has specific permissions. Accepts an array of permission nodes and returns the status for each. **Authentication Required:** Yes **Required Scopes:** `user.read` **Request Body:** ```json { "permissions": ["user.read", "company.create", "credential.write"] } ``` **Response:** ```json { "status": 200, "message": "Permission check completed.", "data": { "results": [ { "permission": "user.read", "hasPermission": true }, { "permission": "company.create", "hasPermission": false }, { "permission": "credential.write", "hasPermission": true } ] }, "successful": true } ``` --- ## Other User Routes ### Get All Users **GET** `/user/users` Fetch a list of all users. **Authentication Required:** Yes **Required Permissions:** `user.read.other`, `user.list.other` **Response:** ```json { "status": 200, "message": "Users Fetched Successfully!", "data": [ { "id": "ckx...", "name": "John Doe", "email": "john.doe@example.com", "login": "john.doe", "image": "https://...", "roles": ["admin"] } ], "successful": true } ``` --- ### Get User by ID **GET** `/user/users/:identifier` Fetch a specific user by their ID. **Authentication Required:** Yes **Required Permissions:** `user.read.other` **Path Parameters:** - `identifier` - The user's ID **Response:** ```json { "status": 200, "message": "User Fetched Successfully!", "data": { "id": "ckx...", "name": "John Doe", "email": "john.doe@example.com", "login": "john.doe", "image": "https://...", "roles": ["admin"] }, "successful": true } ``` **Error Response (404):** ```json { "status": 404, "message": "User with identifier 'ckx...' was not found.", "error": "UserNotFound", "successful": false } ``` --- ### Update User by ID **PATCH** `/user/users/:identifier` Update a specific user's information. Supports updating profile fields, roles, and direct permissions. **Authentication Required:** Yes **Required Permissions:** `user.write.other` **Conditional Permissions:** - If `roles` is included in the body: `user.roles.other` is also required - If `permissions` is included in the body: `user.permissions.other` is also required **Path Parameters:** - `identifier` - The user's ID **Request Body:** All fields are optional. Include only the fields you want to update. ```json { "name": "Jane Doe", "image": "https://example.com/avatar.jpg", "roles": ["admin", "moderator"], "permissions": ["credential.fetch", "company.fetch"] } ``` | Field | Type | Description | | ------------- | ---------- | -------------------------------------------------------------- | | `name` | `string` | The user's display name | | `image` | `string` | URL to the user's avatar image | | `roles` | `string[]` | Array of role ids or monikers to assign (replaces all roles) | | `permissions` | `string[]` | Array of permission nodes to assign (replaces all permissions) | **Response:** ```json { "status": 200, "message": "User Updated Successfully!", "data": { "id": "ckx...", "name": "Jane Doe", "email": "jane.doe@example.com", "login": "jane.doe", "image": "https://example.com/avatar.jpg", "roles": ["admin", "moderator"] }, "successful": true } ``` **Error Response (403 - Missing role permission):** ```json { "status": 403, "message": "You do not have permission to modify roles on another user.", "error": "InsufficientPermission", "successful": false } ``` --- ### Delete User by ID **DELETE** `/user/users/:identifier` Delete a specific user. **Authentication Required:** Yes **Required Permissions:** `user.delete.other` **Path Parameters:** - `identifier` - The user's ID **Response:** ```json { "status": 200, "message": "User Deleted Successfully!", "data": { "id": "ckx...", "name": "John Doe", "email": "john.doe@example.com", "login": "john.doe", "image": "https://...", "roles": ["admin"] }, "successful": true } ``` --- ### Get User Roles **GET** `/user/users/:identifier/roles` Fetch all roles assigned to a specific user. **Authentication Required:** Yes **Required Permissions:** `user.read.other`, `role.read` **Path Parameters:** - `identifier` - The user's ID **Response:** ```json { "status": 200, "message": "User Roles Fetched Successfully!", "data": [ { "id": "uuid...", "title": "Administrator", "moniker": "admin", "permissions": ["*"] } ], "successful": true } ``` --- ### Check User Permissions (Other User) **POST** `/user/users/:identifier/check-permission` Check if a specific user has certain permissions. **Authentication Required:** Yes **Required Permissions:** `user.read.other` **Path Parameters:** - `identifier` - The user's ID **Request Body:** ```json { "permissions": ["user.read", "company.fetch", "credential.write"] } ``` **Response:** ```json { "status": 200, "message": "Permission check completed.", "data": { "results": [ { "permission": "user.read", "hasPermission": true }, { "permission": "company.fetch", "hasPermission": false }, { "permission": "credential.write", "hasPermission": true } ] }, "successful": true } ``` --- ## Company Routes ### Get All Companies **GET** `/company/companies` Fetch a paginated list of all companies with optional search functionality. **Authentication Required:** Yes **Required Permissions:** `company.fetch.many` **Query Parameters:** - `page` (optional) - Page number (default: 1) - `rpp` (optional) - Records per page (default: 30) - `search` (optional) - Search query to filter companies **Response:** ```json { "status": 200, "message": "Companies Fetched Successfully!", "data": [ { "id": "ckx...", "name": "Acme Corp", "cw_CompanyId": 12345, "cw_Identifier": "AcmeCorp" } ], "pagination": { "previousPage": null, "currentPage": 1, "nextPage": 2, "totalPages": 10, "totalRecords": 300, "listedRecords": 30 }, "successful": true } ``` --- ### Get Company by ID **GET** `/company/companies/:identifier` Fetch a single company by its ID. Automatically fetches fresh data from ConnectWise and returns it along with internal company data. **Authentication Required:** Yes **Required Permissions:** - `company.fetch` (base permission) - `company.fetch.address` (required when `includeAddress=true`) **URL Parameters:** - `identifier` - Company ID (internal database ID) **Query Parameters:** - `includeAddress` (optional) - Set to "true" to include full address information. Requires `company.fetch.address` permission. (default: false) **Response (without includeAddress):** ```json { "status": 200, "message": "Company Fetched Successfully!", "data": { "id": "ckx...", "name": "Acme Corp", "cw_CompanyId": 12345, "cw_Identifier": "AcmeCorp", "cw_Data": {} }, "successful": true } ``` **Response (with includeAddress=true):** ```json { "status": 200, "message": "Company Fetched Successfully!", "data": { "id": "ckx...", "name": "Acme Corp", "cw_CompanyId": 12345, "cw_Identifier": "AcmeCorp", "cw_Data": { "address": { "line1": "123 Main St", "line2": null, "city": "Springfield", "state": "IL", "zip": "62701", "country": "United States" } } }, "successful": true } ``` --- ### Get Company Configurations **GET** `/company/companies/:identifier/configurations` Fetch configurations for a specific company from ConnectWise. **Authentication Required:** Yes **Required Permissions:** `company.fetch`, `company.fetch.configurations` **URL Parameters:** - `identifier` - Company ID **Response:** ```json { "status": 200, "message": "Company Configurations Fetched Successfully!", "data": { // ConnectWise configuration data }, "successful": true } ``` --- ## Credential Routes ### Get Value Types **GET** `/credential/valuetypes` Returns all available field value types for credential type fields. **Authentication Required:** Yes **Response:** ```json { "status": 200, "message": "Value Types Fetched Successfully!", "data": [ "plain_text", "license_key", "ip_address", "generic_secret", "bitlocker_key", "password" ], "successful": true } ``` --- ### Get Credential by ID **GET** `/credential/credentials/:id` Fetch a single credential by its ID. **Authentication Required:** Yes **Required Permissions:** `credential.fetch` **URL Parameters:** - `id` - Credential ID **Response:** ```json { "status": 200, "message": "Credential Fetched Successfully!", "data": { "id": "ckx...", "name": "AWS Credentials", "notes": null, "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "secure": false, "required": true, "valueType": "plain_text", "value": "AKIAIOSFODNN7EXAMPLE" }, { "id": "secretAccessKey", "name": "Secret Access Key", "secure": true, "required": true, "valueType": "password", "value": null } ], "type": { "id": "cky...", "name": "AWS", "fields": [...], "permissionScope": "aws.credentials" }, "company": { "id": "ckz...", "name": "Acme Corp" }, "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-02-14T00:00:00.000Z" }, "successful": true } ``` --- ### Get Credentials by Company **GET** `/credential/credentials/company/:companyId` Fetch all credentials associated with a specific company. **Authentication Required:** Yes **Required Permissions:** `credential.fetch.many` **URL Parameters:** - `companyId` - Company ID **Response:** ```json { "status": 200, "message": "Company Credentials Fetched Successfully!", "data": [ { "id": "ckx...", "name": "AWS Credentials", "notes": null, "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "secure": false, "required": true, "valueType": "plain_text", "value": "AKIAIOSFODNN7EXAMPLE" }, { "id": "secretAccessKey", "name": "Secret Access Key", "secure": true, "required": true, "valueType": "password", "value": null } ], "type": {...}, "company": {...} } ], "successful": true } ``` --- ### Create Credential **POST** `/credential/credentials` Create a new credential with validated and encrypted fields. **Authentication Required:** Yes **Required Permissions:** `credential.create` **Request Body:** ```json { "name": "Production AWS Credentials", "notes": "Used for production S3 access", "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "ckx1...", "fieldId": "accessKeyId", "value": "AKIAIOSFODNN7EXAMPLE" }, { "id": "ckx2...", "fieldId": "secretAccessKey", "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" } ] } ``` **Response:** ```json { "status": 201, "message": "Credential Created Successfully!", "data": { "id": "ckx...", "name": "Production AWS Credentials", "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "secure": false, "required": true, "valueType": "plain_text", "value": "AKIAIOSFODNN7EXAMPLE" }, { "id": "secretAccessKey", "name": "Secret Access Key", "secure": true, "required": true, "valueType": "password", "value": null } ], "type": {...}, "company": {...} }, "successful": true } ``` --- ### Update Credential **PATCH** `/credential/credentials/:id` Update a credential's basic properties (name, notes) and/or field values. Secure fields are automatically encrypted. **Authentication Required:** Yes **Required Permissions:** `credential.update` **URL Parameters:** - `id` - Credential ID **Request Body:** All properties are optional. Include only the properties you want to update. ```json { "name": "Updated Credential Name", "notes": "Updated notes for this credential", "fields": [ { "fieldId": "accessKeyId", "value": "AKIAIOSFODNN7EXAMPLE" }, { "fieldId": "secretAccessKey", "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" } ] } ``` **Response:** ```json { "status": 200, "message": "Credential Updated Successfully!", "data": { "id": "ckx...", "name": "Updated Credential Name", "notes": "Updated notes for this credential", "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "secure": false, "required": true, "valueType": "plain_text", "value": "AKIAIOSFODNN7EXAMPLE" } ], "type": {...}, "company": {...} }, "successful": true } ``` --- ### Update Credential Fields **PUT** `/credential/credentials/:id/fields` Validate and update credential field values. Secure fields are automatically encrypted. **Authentication Required:** Yes **Required Permissions:** `credential.update`, `credential.fields.update` **URL Parameters:** - `id` - Credential ID **Request Body:** ```json { "fields": [ { "fieldId": "accessKeyId", "value": "AKIAIOSFODNN7NEWVALUE" }, { "fieldId": "secretAccessKey", "value": "newSecretKeyValue123" } ] } ``` **Response:** ```json { "status": 200, "message": "Credential Fields Updated Successfully!", "data": { "id": "ckx...", "name": "Production AWS Credentials", "notes": null, "typeId": "cky...", "companyId": "ckz...", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "secure": false, "required": true, "valueType": "plain_text", "value": "AKIAIOSFODNN7NEWVALUE" }, { "id": "secretAccessKey", "name": "Secret Access Key", "secure": true, "required": true, "valueType": "password", "value": null } ], "type": {...}, "company": {...} }, "successful": true } ``` --- ### Get Credential Fields **GET** `/credential/credentials/:id/fields` Fetch all field values for a credential (secure fields returned encrypted). **Authentication Required:** Yes **Required Permissions:** `credential.fetch`, `credential.fields.fetch` **URL Parameters:** - `id` - Credential ID **Response:** ```json { "status": 200, "message": "Credential Fields Fetched Successfully!", "data": [ { "id": "ckx-accessKeyId", "fieldId": "accessKeyId", "value": "AKIAIOSFODNN7EXAMPLE" }, { "id": "ckx1...", "fieldId": "secretAccessKey", "value": "base64EncryptedValue==" } ], "successful": true } ``` --- ### Read Secure Values **GET** `/credential/credentials/:id/secure-values` Decrypt and return all secure field values for a credential. **Authentication Required:** Yes **Required Permissions:** `credential.fetch`, `credential.secure_values.read` **URL Parameters:** - `id` - Credential ID **Response:** ```json { "status": 200, "message": "Secure Values Fetched Successfully!", "data": { "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "apiKey": "sk_live_123456789abcdef" }, "successful": true } ``` --- ### Read Single Secure Value **GET** `/credential/credentials/:id/secure-values/:fieldId` Decrypt and return a single secure field value for a credential. **Authentication Required:** Yes **Required Permissions:** `credential.fetch`, `credential.secure_values.read` **URL Parameters:** - `id` - Credential ID - `fieldId` - The field ID of the secure value to read **Response:** ```json { "status": 200, "message": "Secure Value Fetched Successfully!", "data": { "fieldId": "secretAccessKey", "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" }, "successful": true } ``` **Error Response (404):** ```json { "status": 404, "message": "Secure field not found: unknownField", "error": "SecureFieldNotFound", "successful": false } ``` --- ### Delete Credential **DELETE** `/credential/credentials/:id` Delete a credential and all associated secure values. **Authentication Required:** Yes **Required Permissions:** `credential.delete` **URL Parameters:** - `id` - Credential ID **Response:** ```json { "status": 200, "message": "Credential Deleted Successfully!", "data": null, "successful": true } ``` --- ## Credential Type Routes ### Get Credential Type by ID or Name **GET** `/credential-type/:identifier` Fetch a single credential type by its ID or name. **Authentication Required:** Yes **Required Permissions:** `credential_type.fetch` **URL Parameters:** - `identifier` - Credential Type ID or name **Response:** ```json { "status": 200, "message": "Credential Type Fetched Successfully!", "data": { "id": "cky...", "name": "AWS", "permissionScope": "aws.credentials", "icon": "https://aws.amazon.com/favicon.ico", "fields": [ { "id": "accessKeyId", "name": "Access Key ID", "required": true, "secure": false, "valueType": "plain_text" }, { "id": "secretAccessKey", "name": "Secret Access Key", "required": true, "secure": true, "valueType": "password" } ], "credentialCount": 5, "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-02-14T00:00:00.000Z" }, "successful": true } ``` --- ### Get All Credential Types **GET** `/credential-type` Fetch all credential types in the system. **Authentication Required:** Yes **Required Permissions:** `credential_type.fetch.many` **Response:** ```json { "status": 200, "message": "Credential Types Fetched Successfully!", "data": [ { "id": "cky...", "name": "AWS", "permissionScope": "aws.credentials", "icon": "https://aws.amazon.com/favicon.ico", "fields": [...], "credentialCount": 5 }, { "id": "ckz...", "name": "Azure", "permissionScope": "azure.credentials", "icon": "https://azure.microsoft.com/favicon.ico", "fields": [...], "credentialCount": 3 } ], "successful": true } ``` --- ### Create Credential Type **POST** `/credential-type` Create a new credential type with field definitions. **Authentication Required:** Yes **Required Permissions:** `credential_type.create` **Request Body:** ```json { "name": "GitHub", "permissionScope": "github.credentials", "icon": "https://github.com/favicon.ico", "fields": [ { "id": "username", "name": "Username", "required": true, "secure": false, "valueType": "plain_text" }, { "id": "personalAccessToken", "name": "Personal Access Token", "required": true, "secure": true, "valueType": "password" } ] } ``` **Response:** ```json { "status": 201, "message": "Credential Type Created Successfully!", "data": { "id": "ck1...", "name": "GitHub", "permissionScope": "github.credentials", "icon": "https://github.com/favicon.ico", "fields": [...] }, "successful": true } ``` --- ### Update Credential Type **PATCH** `/credential-type/:id` Update a credential type's properties or field definitions. **Authentication Required:** Yes **Required Permissions:** `credential_type.update` **URL Parameters:** - `id` - Credential Type ID **Request Body:** ```json { "name": "GitHub Enterprise", "icon": "https://github.enterprise.com/favicon.ico", "fields": [ { "id": "username", "name": "Username", "required": true, "secure": false, "valueType": "plain_text" }, { "id": "personalAccessToken", "name": "Personal Access Token", "required": true, "secure": true, "valueType": "password" }, { "id": "enterpriseUrl", "name": "Enterprise URL", "required": true, "secure": false, "valueType": "plain_text" } ] } ``` **Response:** ```json { "status": 200, "message": "Credential Type Updated Successfully!", "data": { "id": "ck1...", "name": "GitHub Enterprise", "fields": [...] }, "successful": true } ``` --- ### Delete Credential Type **DELETE** `/credential-type/:id` Delete a credential type. This will cascade delete all credentials of this type. **Authentication Required:** Yes **Required Permissions:** `credential_type.delete` **URL Parameters:** - `id` - Credential Type ID **Response:** ```json { "status": 200, "message": "Credential Type Deleted Successfully!", "data": null, "successful": true } ``` --- ### Get Credentials by Type **GET** `/credential-type/:id/credentials` Fetch all credentials that use a specific credential type. **Authentication Required:** Yes **Required Permissions:** `credential_type.fetch`, `credential.fetch.many` **URL Parameters:** - `id` - Credential Type ID **Response:** ```json { "status": 200, "message": "Credentials Fetched Successfully!", "data": [ { "id": "ckx...", "name": "Production AWS", "typeId": "cky...", "companyId": "ckz...", "fields": {...} }, { "id": "ck2...", "name": "Staging AWS", "typeId": "cky...", "companyId": "ckz...", "fields": {...} } ], "successful": true } ``` --- ## Role Routes ### Create Role **POST** `/role` Create a new role with a title, moniker, and optional permissions. **Authentication Required:** Yes **Required Permissions:** `role.create` **Request Body:** ```json { "title": "System Administrator", "moniker": "system_admin", "permissions": [ "user.read", "user.write", "company.fetch", "credential.create" ] } ``` **Response:** ```json { "status": 201, "message": "Role Created Successfully!", "data": { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "permissions": [ "user.read", "user.write", "company.fetch", "credential.create" ], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T00:00:00.000Z" }, "successful": true } ``` --- ### Get Role by ID or Moniker **GET** `/role/:identifier` Fetch a single role by its ID or moniker. **Authentication Required:** Yes **Required Permissions:** `role.read` **URL Parameters:** - `identifier` - Role ID or moniker **Response:** ```json { "status": 200, "message": "Role Fetched Successfully!", "data": { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "permissions": [ "user.read", "user.write", "company.fetch", "credential.create" ], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T00:00:00.000Z" }, "successful": true } ``` --- ### Get All Roles **GET** `/role` Fetch all roles in the system. **Authentication Required:** Yes **Required Permissions:** `role.read`, `role.list` **Response:** ```json { "status": 200, "message": "Roles Fetched Successfully!", "data": [ { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "permissions": ["user.read", "user.write"], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T00:00:00.000Z" }, { "id": "cky...", "title": "Viewer", "moniker": "viewer", "permissions": ["user.read", "company.fetch"], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T00:00:00.000Z" } ], "successful": true } ``` --- ### Update Role **PATCH** `/role/:identifier` Update a role's title, moniker, or permissions. **Authentication Required:** Yes **Required Permissions:** `role.modify` **URL Parameters:** - `identifier` - Role ID or moniker **Request Body:** ```json { "title": "Super Administrator", "moniker": "super_admin", "permissions": ["*"] } ``` **Response:** ```json { "status": 200, "message": "Role Updated Successfully!", "data": { "id": "ckx...", "title": "Super Administrator", "moniker": "super_admin", "permissions": ["*"], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T12:00:00.000Z" }, "successful": true } ``` --- ### Delete Role **DELETE** `/role/:identifier` Delete a role. This will remove the role from all users that have it assigned. **Authentication Required:** Yes **Required Permissions:** `role.delete` **URL Parameters:** - `identifier` - Role ID or moniker **Response:** ```json { "status": 200, "message": "Role Deleted Successfully!", "data": { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T12:00:00.000Z" }, "successful": true } ``` --- ### Add Permissions to Role **POST** `/role/:identifier/permissions` Add one or more permissions to an existing role. The new permissions will be merged with existing permissions. **Authentication Required:** Yes **Required Permissions:** `role.modify` **URL Parameters:** - `identifier` - Role ID or moniker **Request Body:** ```json { "permissions": ["credential.update", "credential.delete"] } ``` **Response:** ```json { "status": 200, "message": "Permissions Added Successfully!", "data": { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "permissions": [ "user.read", "user.write", "company.fetch", "credential.create", "credential.update", "credential.delete" ], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T12:30:00.000Z" }, "successful": true } ``` --- ### Remove Permissions from Role **DELETE** `/role/:identifier/permissions` Remove one or more permissions from an existing role. **Authentication Required:** Yes **Required Permissions:** `role.modify` **URL Parameters:** - `identifier` - Role ID or moniker **Request Body:** ```json { "permissions": ["credential.delete"] } ``` **Response:** ```json { "status": 200, "message": "Permissions Removed Successfully!", "data": { "id": "ckx...", "title": "System Administrator", "moniker": "system_admin", "permissions": [ "user.read", "user.write", "company.fetch", "credential.create", "credential.update" ], "createdAt": "2026-02-17T00:00:00.000Z", "updatedAt": "2026-02-17T12:45:00.000Z" }, "successful": true } ``` --- ### Get Users with Role **GET** `/role/:identifier/users` Fetch all users that have been assigned a specific role. **Authentication Required:** Yes **Required Permissions:** `role.read`, `user.read` **URL Parameters:** - `identifier` - Role ID or moniker **Response:** ```json { "status": 200, "message": "Users Fetched Successfully!", "data": [ { "id": "cku...", "name": "John Doe", "login": "john.doe", "roles": ["ckx..."], "createdAt": "2026-01-15T00:00:00.000Z", "updatedAt": "2026-02-10T00:00:00.000Z" }, { "id": "ckv...", "name": "Jane Smith", "login": "jane.smith", "roles": ["ckx...", "cky..."], "createdAt": "2026-01-20T00:00:00.000Z", "updatedAt": "2026-02-12T00:00:00.000Z" } ], "successful": true } ``` --- ## Permission Routes ### Get All Permission Nodes (Categorized) **GET** `/permissions` Fetch all permission nodes organized by category. Returns the full permission node definition object with categories as keys. **Authentication Required:** Yes **Required Permissions:** `role.read` **Response:** ```json { "status": 200, "message": "Permission Nodes Fetched Successfully!", "data": { "global": { "name": "Global Permissions", "description": "Global wildcard permissions that grant access to all resources", "permissions": [ { "node": "*", "description": "Full access to all resources and actions (administrator role)", "usedIn": [] } ] }, "company": { "..." }, "credential": { "..." }, "...additional categories": { "..." } }, "successful": true } ``` --- ### Get All Permission Nodes (Flat) **GET** `/permissions/nodes` Fetch a flat array of all permission nodes across all categories. **Authentication Required:** Yes **Required Permissions:** `role.read` **Response:** ```json { "status": 200, "message": "All Permission Nodes Fetched Successfully!", "data": [ { "node": "*", "description": "Full access to all resources and actions (administrator role)", "usedIn": [] }, { "node": "company.fetch", "description": "Fetch a single company", "usedIn": ["src/api/companies/[id]/fetch.ts"] }, "...additional nodes" ], "successful": true } ``` --- ### Get Permission Nodes by Category **GET** `/permissions/:category` Fetch all permission nodes for a specific category. **Authentication Required:** Yes **Required Permissions:** `role.read` **Path Parameters:** - `category` - The category key (e.g., `global`, `company`, `credential`, `credentialType`, `role`, `user`, `permission`, `uiNavigation`, `adminUI`) **Response (Success):** ```json { "status": 200, "message": "Permission Category Fetched Successfully!", "data": { "name": "Company Permissions", "description": "Permissions for accessing and managing company resources", "permissions": [ { "node": "company.fetch", "description": "Fetch a single company", "usedIn": ["src/api/companies/[id]/fetch.ts"] }, { "node": "company.fetch.address", "description": "View company address information", "usedIn": ["src/api/companies/[id]/fetch.ts"], "dependencies": ["company.fetch"] } ] }, "successful": true } ``` **Response (Not Found):** ```json { "status": 404, "message": "Permission category \"invalidCategory\" not found", "error": "NotFound", "successful": false } ``` --- ## Utility Routes ### Teapot **GET** `/teapot` A fun Easter egg endpoint that returns HTTP 418 (I'm a teapot). **Authentication Required:** No **Response:** ```json { "status": 418, "message": "I'm a teapot", "successful": false } ``` --- ## Error Responses All endpoints may return error responses in the following format: ### 400 Bad Request ```json { "status": 400, "message": "Validation error", "errors": [ { "path": ["field"], "message": "Field is required" } ], "successful": false } ``` ### 401 Unauthorized ```json { "status": 401, "message": "Unauthorized", "successful": false } ``` ### 403 Forbidden ```json { "status": 403, "message": "Insufficient permissions", "successful": false } ``` ### 404 Not Found ```json { "status": 404, "message": "Resource not found", "successful": false } ``` ### 500 Internal Server Error ```json { "status": 500, "message": "Internal server error", "successful": false } ``` --- ## Authentication Most endpoints require authentication via an access token in the request headers: ``` Authorization: Bearer ``` Tokens are obtained through the Microsoft OAuth flow: 1. Call `GET /auth/uri` to get the authentication URL 2. Redirect user to the Microsoft login page 3. User authenticates and is redirected to `/auth/redirect` 4. Access and refresh tokens are provided via WebSocket or response 5. Use the access token in subsequent API requests When the access token expires, use `POST /auth/refresh` with the refresh token to obtain a new access token. --- ## Permission System The API uses a granular permission system. Each endpoint requires specific permissions that are checked via the `authMiddleware`. Permissions are granted through roles assigned to users. Common permission patterns: - `resource.fetch` - Read a single resource - `resource.fetch.many` - Read multiple resources - `resource.create` - Create a new resource - `resource.update` - Update a resource - `resource.delete` - Delete a resource - `resource.field.action` - Perform specific field operations Users can have multiple roles, and permissions are accumulated from all assigned roles.