Files
optima/API_ROUTES.md
T
2026-02-20 11:46:30 -06:00

35 KiB

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:

{
  "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:

{
  "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:

{
  "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:

{
  "name": "Jane Doe",
  "image": "https://example.com/avatar.jpg"
}

Response:

{
  "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:

{
  "permissions": ["user.read", "company.create", "credential.write"]
}

Response:

{
  "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:

{
  "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:

{
  "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):

{
  "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.

{
  "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:

{
  "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):

{
  "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:

{
  "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:

{
  "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:

{
  "permissions": ["user.read", "company.fetch", "credential.write"]
}

Response:

{
  "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:

{
  "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):

{
  "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):

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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.

{
  "name": "Updated Credential Name",
  "notes": "Updated notes for this credential",
  "fields": [
    {
      "fieldId": "accessKeyId",
      "value": "AKIAIOSFODNN7EXAMPLE"
    },
    {
      "fieldId": "secretAccessKey",
      "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
    }
  ]
}

Response:

{
  "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:

{
  "fields": [
    {
      "fieldId": "accessKeyId",
      "value": "AKIAIOSFODNN7NEWVALUE"
    },
    {
      "fieldId": "secretAccessKey",
      "value": "newSecretKeyValue123"
    }
  ]
}

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "status": 200,
  "message": "Secure Value Fetched Successfully!",
  "data": {
    "fieldId": "secretAccessKey",
    "value": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  },
  "successful": true
}

Error Response (404):

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "title": "System Administrator",
  "moniker": "system_admin",
  "permissions": [
    "user.read",
    "user.write",
    "company.fetch",
    "credential.create"
  ]
}

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "title": "Super Administrator",
  "moniker": "super_admin",
  "permissions": ["*"]
}

Response:

{
  "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:

{
  "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:

{
  "permissions": ["credential.update", "credential.delete"]
}

Response:

{
  "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:

{
  "permissions": ["credential.delete"]
}

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "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):

{
  "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):

{
  "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:

{
  "status": 418,
  "message": "I'm a teapot",
  "successful": false
}

Error Responses

All endpoints may return error responses in the following format:

400 Bad Request

{
  "status": 400,
  "message": "Validation error",
  "errors": [
    {
      "path": ["field"],
      "message": "Field is required"
    }
  ],
  "successful": false
}

401 Unauthorized

{
  "status": 401,
  "message": "Unauthorized",
  "successful": false
}

403 Forbidden

{
  "status": 403,
  "message": "Insufficient permissions",
  "successful": false
}

404 Not Found

{
  "status": 404,
  "message": "Resource not found",
  "successful": false
}

500 Internal Server Error

{
  "status": 500,
  "message": "Internal server error",
  "successful": false
}

Authentication

Most endpoints require authentication via an access token in the request headers:

Authorization: Bearer <access_token>

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.