OpenAPI JSONMarkdown Docs

OpenAPI Explorer

Auto-generated OpenAPI definition for all enabled modules.

Default server: https://server.tail3470ec.ts.net/api

Authentication & Accounts

Showing 20 of 35 endpoints
GET/auth/admin/nav
Auth required

Resolve backend chrome bootstrap payload

Returns the backend chrome payload available to the authenticated administrator after applying scope, RBAC, role defaults, and personal sidebar preferences.

Responses

200Backend chrome payload
Content-Type: application/json
{
  "brand": null,
  "groups": [
    {
      "name": "string",
      "items": [
        {
          "href": "string",
          "title": "string"
        }
      ]
    }
  ],
  "settingsSections": [
    {
      "id": "string",
      "label": "string",
      "items": [
        {
          "id": "string",
          "label": "string",
          "href": "string"
        }
      ]
    }
  ],
  "settingsPathPrefixes": [
    "string"
  ],
  "profileSections": [
    {
      "id": "string",
      "label": "string",
      "items": [
        {
          "id": "string",
          "label": "string",
          "href": "string"
        }
      ]
    }
  ],
  "profilePathPrefixes": [
    "string"
  ],
  "grantedFeatures": [
    "string"
  ],
  "roles": [
    "string"
  ],
  "currentOrganization": null
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/admin/nav" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/autologin

Auto sign-in using env-configured demo credentials

When OM_AUTOLOGIN_EMAIL / OM_AUTOLOGIN_PASSWORD are configured, signs the visitor in with those credentials and redirects into the app. Intended for single-tenant demo instances only. Falls back to the login page when disabled or misconfigured.

Responses

200Success response
Content-Type: application/json
"string"
307Redirect into the app (or to /login on failure)
Content-Type: text/html
string

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/autologin" \
  -H "Accept: application/json"
POST/auth/feature-check
Auth required

Check feature grants for the current user

Evaluates which of the requested features are available to the signed-in user within the active tenant / organization context.

Request body (application/json)

{
  "features": [
    "string"
  ]
}

Responses

200Evaluation result
Content-Type: application/json
{
  "ok": true,
  "granted": [
    "string"
  ],
  "userId": "string"
}
400Invalid request — features array missing, too large, or contains invalid entries
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/feature-check" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
GET/auth/features
Auth required

List declared feature flags

Returns all static features contributed by the enabled modules along with their module source.

Responses

200Aggregated feature catalog
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "module": "string"
    }
  ],
  "modules": [
    {
      "id": "string",
      "title": "string"
    }
  ]
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/features" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/locale

Set locale and redirect

Stores the selected locale in a cookie and redirects to a safe local path.

Parameters

NameInRequiredSchemaDescription
localequeryYesany—
redirectqueryNoany—

Responses

200Success response
Content-Type: application/json
"string"
302Locale cookie set and request redirected
Content-Type: application/json
"string"
400Invalid locale
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/locale?locale=en" \
  -H "Accept: application/json"
POST/auth/locale

Set locale

Stores the selected locale in a cookie and returns a JSON success response.

Request body (application/json)

{
  "locale": "en"
}

Responses

200Locale cookie set
Content-Type: application/json
{
  "ok": true
}
400Invalid locale or malformed request body
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/locale" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"locale\": \"en\"
}"
POST/auth/login

Authenticate user credentials

Validates the submitted credentials and issues a bearer token cookie for subsequent API calls.

Request body (application/x-www-form-urlencoded)

email=user%40example.com&password=string

Responses

200Authentication succeeded
Content-Type: application/json
{
  "ok": true,
  "token": "string",
  "redirect": null
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid credentials
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403User lacks required role
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many login attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=user%40example.com&password=string"
POST/auth/logout
Auth required

Invalidate session and redirect

Clears authentication cookies and redirects the browser to the login page.

Responses

201Success response
Content-Type: application/json
"string"
302Redirect to login after successful logout
Content-Type: text/html
string

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/profile
Auth required

Get current profile

Returns the email address, display name, and roles for the signed-in user. The display name is null when unset.

Responses

200Profile payload
Content-Type: application/json
{
  "email": "user@example.com",
  "name": null,
  "roles": [
    "string"
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/profile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/auth/profile
Auth required

Update current profile

Updates the email address or password for the signed-in user.

Request body (application/json)

{}

Responses

200Profile updated
Content-Type: application/json
{
  "ok": true,
  "email": "user@example.com"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/auth/profile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/auth/reset

Send reset email

Requests a password reset email for the given account. The endpoint always returns `ok: true` to avoid leaking account existence.

Request body (application/x-www-form-urlencoded)

email=user%40example.com

Responses

200Reset email dispatched (or ignored for unknown accounts)
Content-Type: application/json
{
  "ok": true
}
400Invalid request origin
Content-Type: application/json
{
  "error": "string"
}
429Too many password reset requests
Content-Type: application/json
{
  "error": "string"
}
500Password reset email origin is not configured
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/reset" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=user%40example.com"
POST/auth/reset/confirm

Complete password reset

Validates the reset token and updates the user password.

Request body (application/x-www-form-urlencoded)

token=string&password=string

Responses

200Password reset succeeded
Content-Type: application/json
{
  "ok": true,
  "redirect": "string"
}
400Invalid token or payload
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many reset confirmation attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/reset/confirm" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=string&password=string"
GET/auth/roles
Auth required

List roles

Returns available roles within the current tenant. Super administrators receive visibility across tenants.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
tenantIdqueryNoany—

Responses

200Role collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "usersCount": 1,
      "tenantId": null,
      "tenantName": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/roles?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/auth/roles
Auth required

Create role

Creates a new role anchored to the caller's tenant. Non-superadmins cannot target another tenant; supplying a foreign `tenantId` is rejected.

Request body (application/json)

{
  "name": "string"
}

Responses

201Role created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/auth/roles
Auth required

Update role

Updates mutable fields on an existing role.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Role updated
Content-Type: application/json
{
  "ok": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/auth/roles
Auth required

Delete role

Deletes a role by identifier. Fails when users remain assigned.

Parameters

NameInRequiredSchemaDescription
idqueryYesanyRole identifier

Responses

200Role deleted
Content-Type: application/json
{
  "ok": true
}
400Role cannot be deleted
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/auth/roles?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/roles/acl
Auth required

Fetch role ACL

Returns the feature and organization assignments associated with a role within the current tenant.

Parameters

NameInRequiredSchemaDescription
roleIdqueryYesany—
tenantIdqueryNoany—

Responses

200Role ACL entry
Content-Type: application/json
{
  "isSuperAdmin": true,
  "features": [
    "string"
  ],
  "organizations": null,
  "updatedAt": null
}
400Invalid role id
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/roles/acl?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/auth/roles/acl
Auth required

Update role ACL

Replaces the feature list, super admin flag, and optional organization assignments for a role.

Request body (application/json)

{
  "roleId": "00000000-0000-4000-8000-000000000000",
  "organizations": null
}

Responses

200Role ACL updated
Content-Type: application/json
{
  "ok": true,
  "sanitized": true
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Insufficient privileges to modify ACL
Content-Type: application/json
{
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/auth/roles/acl" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleId\": \"00000000-0000-4000-8000-000000000000\",
  \"organizations\": null
}"
GET/auth/session/refresh

Refresh auth cookie from session token (browser)

Exchanges an existing `session_token` cookie for a fresh JWT auth cookie and redirects the browser.

Parameters

NameInRequiredSchemaDescription
redirectqueryNoanyAbsolute or relative URL to redirect after refresh

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to target location when session is valid
Content-Type: text/html
string

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/session/refresh" \
  -H "Accept: application/json"
POST/auth/session/refresh

Refresh access token (API/mobile)

Exchanges a refresh token for a new JWT access token. Pass the refresh token obtained from login in the request body.

Request body (application/json)

{
  "refreshToken": "string"
}

Responses

200New access token issued
Content-Type: application/json
{
  "ok": true,
  "accessToken": "string",
  "expiresIn": 1
}
400Missing refresh token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid or expired token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many refresh attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/auth/session/refresh" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"refreshToken\": \"string\"
}"

Directory (Tenants & Organizations)

Showing 2 of 2 endpoints
GET/directory/organizations/lookup

Public organization lookup by slug

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/organizations/lookup" \
  -H "Accept: application/json"
GET/directory/tenants/lookup

Public tenant lookup

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/tenants/lookup" \
  -H "Accept: application/json"

API Documentation

Showing 1 of 1 endpoints
GET/version

Deployed Open Mercato version

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/version" \
  -H "Accept: application/json"

Audit & Action Logs

Showing 5 of 5 endpoints
GET/audit_logs/audit-logs/access
Auth required

Retrieve access logs

Fetches paginated access audit logs scoped to the authenticated user. Tenant administrators can optionally expand the search to other actors or organizations.

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter by actor user id (tenant administrators only)
resourceKindqueryNoanyRestrict to a resource kind such as `order` or `product`
accessTypequeryNoanyAccess type filter, e.g. `read` or `export`
pagequeryNoanyPage number (default 1)
pageSizequeryNoanyPage size (default 50)
limitqueryNoanyExplicit maximum number of records when paginating manually
beforequeryNoanyReturn logs created before this ISO-8601 timestamp
afterqueryNoanyReturn logs created after this ISO-8601 timestamp

Responses

200Access logs returned successfully
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "resourceKind": "string",
      "resourceId": "string",
      "accessType": "string",
      "actorUserId": null,
      "actorUserName": null,
      "tenantId": null,
      "tenantName": null,
      "organizationId": null,
      "organizationName": null,
      "fields": [
        "string"
      ],
      "context": null,
      "createdAt": "string"
    }
  ],
  "canViewTenant": true,
  "page": 1,
  "pageSize": 1,
  "total": 1,
  "totalPages": 1
}
400Invalid filters supplied
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Caller has no resolved tenant scope and is not a superadmin
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/audit_logs/audit-logs/access" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/audit_logs/audit-logs/actions
Auth required

Fetch action logs

Returns recent action audit log entries. Tenant administrators can widen the scope to other actors or organizations, and callers can optionally restrict results to undoable actions.

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter logs created by specific actor IDs (tenant administrators only). Accepts a single UUID or a comma-separated UUID list.
resourceKindqueryNoanyFilter by resource kind (e.g., "order", "product")
resourceIdqueryNoanyFilter by resource ID (UUID of the specific record)
actionTypequeryNoanyFilter by action type (`create`, `edit`, `delete`, `assign`). Accepts a single value or a comma-separated list.
fieldNamequeryNoanyFilter to entries where the given field changed. Accepts a single field name or a comma-separated list.
includeRelatedqueryNoanyWhen `true`, also returns changes to child entities linked via parentResourceKind/parentResourceId
includeTotalqueryNoanyWhen `true`, the response includes the filtered total count.
undoableOnlyqueryNoanyWhen `true`, only undoable actions are returned
limitqueryNoanyMaximum number of records to return (default 50, max 1000)
offsetqueryNoanyZero-based record offset for pagination (legacy — prefer page/pageSize)
pagequeryNoanyPage number (default 1)
pageSizequeryNoanyPage size (default 50, max 200)
sortFieldqueryNoanySort field: `createdAt`, `user`, `action`, `field`, or `source`.
sortDirqueryNoanySort direction: `asc` or `desc`.
beforequeryNoanyReturn actions created before this ISO-8601 timestamp
afterqueryNoanyReturn actions created after this ISO-8601 timestamp

Responses

200Action logs retrieved successfully
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "commandId": "string",
      "actionLabel": null,
      "executionState": "done",
      "actorUserId": null,
      "actorUserName": null,
      "tenantId": null,
      "tenantName": null,
      "organizationId": null,
      "organizationName": null,
      "resourceKind": null,
      "resourceId": null,
      "parentResourceKind": null,
      "parentResourceId": null,
      "undoToken": null,
      "createdAt": "string",
      "updatedAt": "string",
      "snapshotBefore": null,
      "snapshotAfter": null,
      "changes": null,
      "context": null
    }
  ],
  "canViewTenant": true,
  "page": 1,
  "pageSize": 1,
  "total": 1,
  "totalPages": 1
}
400Invalid filter values
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Caller has no resolved tenant scope and is not a superadmin
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/audit_logs/audit-logs/actions?includeRelated=false&includeTotal=false&undoableOnly=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/audit_logs/audit-logs/actions/export
Auth required

Export action logs as CSV

Returns a CSV attachment containing filtered action audit log entries. Tenant administrators can widen the scope to other actors or organizations.

Parameters

NameInRequiredSchemaDescription
organizationIdqueryNoanyLimit results to a specific organization
actorUserIdqueryNoanyFilter logs created by specific actor IDs (tenant administrators only). Accepts a single UUID or a comma-separated UUID list.
resourceKindqueryNoanyFilter by resource kind (e.g., "order", "product")
resourceIdqueryNoanyFilter by resource ID (UUID of the specific record)
actionTypequeryNoanyFilter by action type (`create`, `edit`, `delete`, `assign`). Accepts a single value or a comma-separated list.
fieldNamequeryNoanyFilter to entries where the given field changed. Accepts a single field name or a comma-separated list.
includeRelatedqueryNoanyWhen `true`, also returns changes to child entities linked via parentResourceKind/parentResourceId
undoableOnlyqueryNoanyWhen `true`, only undoable actions are returned
limitqueryNoanyMaximum number of records to export (default 1000, capped at 1000)
sortFieldqueryNoanySort field: `createdAt`, `user`, `action`, `field`, or `source`.
sortDirqueryNoanySort direction: `asc` or `desc`.
beforequeryNoanyReturn actions created before this ISO-8601 timestamp
afterqueryNoanyReturn actions created after this ISO-8601 timestamp

Responses

200CSV export generated successfully
Content-Type: application/json
{
  "file": "csv"
}
400Invalid filter values
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Caller has no resolved tenant scope and is not a superadmin
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/audit_logs/audit-logs/actions/export?includeRelated=false&undoableOnly=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/audit_logs/audit-logs/actions/redo
Auth required

Redo by action log id

Redoes the latest undone command owned by the caller. Requires the action to still be eligible for redo within tenant and organization scope.

Request body (application/json)

{
  "logId": "string"
}

Responses

200Redo executed successfully
Content-Type: application/json
{
  "ok": true,
  "logId": null,
  "undoToken": null
}
400Log not eligible for redo
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Redo blocked by scope checks
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/audit_logs/audit-logs/actions/redo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"logId\": \"string\"
}"
POST/audit_logs/audit-logs/actions/undo
Auth required

Undo action by token

Replays the undo handler registered for a command. The provided undo token must match the latest undoable log entry accessible to the caller.

Request body (application/json)

{
  "undoToken": "string"
}

Responses

200Undo applied successfully
Content-Type: application/json
{
  "ok": true,
  "logId": "string"
}
400Invalid or unavailable undo token
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Undo blocked by organization or tenant scope
Content-Type: application/json
{
  "error": "string"
}
422Undo deliberately blocked by a beforeUndo command interceptor. The interceptor chooses the status (any 4xx/5xx) and may replace the body.
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/audit_logs/audit-logs/actions/undo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"undoToken\": \"string\"
}"

Notifications

Showing 20 of 22 endpoints
GET/notifications
Auth required

List notifications

Returns a paginated collection of notifications.

Parameters

NameInRequiredSchemaDescription
statusqueryNoany—
typequeryNoany—
severityqueryNoany—
sourceEntityTypequeryNoany—
sourceEntityIdqueryNoany—
sincequeryNoany—
pagequeryNoany—
pageSizequeryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated notifications
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "type": "string",
      "title": "string",
      "body": null,
      "titleKey": null,
      "bodyKey": null,
      "titleVariables": null,
      "bodyVariables": null,
      "icon": null,
      "severity": "string",
      "status": "string",
      "actions": [
        {
          "id": "string",
          "label": "string"
        }
      ],
      "sourceModule": null,
      "sourceEntityType": null,
      "sourceEntityId": null,
      "linkHref": null,
      "createdAt": "string",
      "readAt": null,
      "actionTaken": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
403Request could not be resolved to a tenant scope (code: tenant_scope_required)
Content-Type: application/json
{
  "error": "string",
  "code": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications
Auth required

Create notification

Creates a notification for a user.

Request body (application/json)

{
  "type": "string",
  "severity": "info",
  "recipientUserId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Notification created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"type\": \"string\",
  \"severity\": \"info\",
  \"recipientUserId\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/notifications/{id}/action
Auth required

POST /notifications/{id}/action

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications/:id/action" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/dismiss
Auth required

PUT /notifications/{id}/dismiss

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/:id/dismiss" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/read
Auth required

PUT /notifications/{id}/read

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/:id/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/{id}/restore
Auth required

PUT /notifications/{id}/restore

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/:id/restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/admin/preferences
Auth required

GET /notifications/admin/preferences

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications/admin/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/admin/preferences
Auth required

PUT /notifications/admin/preferences

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/admin/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/batch
Auth required

POST /notifications/batch

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications/batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/channels
Auth required

GET /notifications/channels

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications/channels" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/feature
Auth required

POST /notifications/feature

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications/feature" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/mark-all-read
Auth required

PUT /notifications/mark-all-read

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/mark-all-read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/preferences
Auth required

GET /notifications/preferences

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/preferences
Auth required

PUT /notifications/preferences

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/role
Auth required

POST /notifications/role

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications/role" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/settings
Auth required

GET /notifications/settings

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/settings
Auth required

POST /notifications/settings

Responses

201Success response
Content-Type: application/json
"string"

Example

curl -X POST "https://server.tail3470ec.ts.net/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/types
Auth required

GET /notifications/types

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/notifications/types" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/notifications/types
Auth required

PATCH /notifications/types

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PATCH "https://server.tail3470ec.ts.net/api/notifications/types" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/notifications/types/{id}/channels/{channel}
Auth required

PUT /notifications/types/{id}/channels/{channel}

Parameters

NameInRequiredSchemaDescription
idpathYesany—
channelpathYesany—

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/notifications/types/:id/channels/:channel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Events

Showing 2 of 2 endpoints
GET/events
Auth required

List declared events

Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true).

Responses

200Declared events
Content-Type: application/json
{
  "data": [
    {
      "id": "string",
      "label": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/events" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/events/stream
Auth required

GET /events/stream

Responses

200Success response
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/events/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Search

Showing 15 of 15 endpoints
GET/search/embeddings
Auth required

Get embeddings configuration

Returns current embedding provider and model configuration.

Responses

200Embeddings settings
Content-Type: application/json
{
  "settings": {
    "openaiConfigured": true,
    "autoIndexingEnabled": true,
    "autoIndexingLocked": true,
    "lockReason": null,
    "embeddingConfig": null,
    "configuredProviders": [
      "openai"
    ],
    "indexedDimension": null,
    "reindexRequired": true,
    "documentCount": null
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/embeddings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/embeddings
Auth required

Update embeddings configuration

Updates the embedding provider and model settings.

Request body (application/json)

{}

Responses

200Updated settings
Content-Type: application/json
{
  "settings": {
    "openaiConfigured": true,
    "autoIndexingEnabled": true,
    "autoIndexingLocked": true,
    "lockReason": null,
    "embeddingConfig": null,
    "configuredProviders": [
      "openai"
    ],
    "indexedDimension": null,
    "reindexRequired": true,
    "documentCount": null
  }
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
409Auto-indexing disabled via environment
Content-Type: application/json
{
  "error": "string"
}
500Update failed
Content-Type: application/json
{
  "error": "string"
}
503Configuration service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/embeddings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/embeddings/reindex
Auth required

Trigger vector reindex

Starts a vector embedding reindex operation.

Request body (application/json)

{}

Responses

200Reindex result
Content-Type: application/json
{
  "ok": true
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
409Reindex already in progress
Content-Type: application/json
{
  "error": "string",
  "lock": {
    "type": "fulltext",
    "action": "string",
    "startedAt": "string",
    "elapsedMinutes": 1,
    "processedCount": null,
    "totalCount": null
  }
}
500Reindex failed
Content-Type: application/json
{
  "error": "string"
}
503Search indexer unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/embeddings/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/embeddings/reindex/cancel
Auth required

Cancel vector reindex

Cancels an in-progress vector reindex operation.

Responses

200Cancel result
Content-Type: application/json
{
  "ok": true,
  "jobsRemoved": 1
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/embeddings/reindex/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/index
Auth required

List vector index entries

Returns paginated list of entries in the vector search index.

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoanyFilter by entity ID (e.g., "customers:customer_person_profile", "catalog:catalog_product")
limitqueryNoanyMaximum entries to return (default: 50, max: 200)
offsetqueryNoanyOffset for pagination (default: 0)

Responses

200Index entries
Content-Type: application/json
{
  "entries": [
    {
      "id": "string",
      "entityId": "string",
      "recordId": "string",
      "tenantId": "string",
      "organizationId": null
    }
  ],
  "limit": 1,
  "offset": 1
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to fetch index
Content-Type: application/json
{
  "error": "string"
}
503Vector strategy unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/index" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/search/index
Auth required

Purge vector index

Purges entries from the vector search index. Requires confirmAll=true when purging all entities.

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoanySpecific entity ID to purge (e.g., "customers:customer_person_profile", "catalog:catalog_product")
confirmAllqueryNoanyRequired when purging all entities

Responses

200Purge result
Content-Type: application/json
{
  "ok": true
}
400Missing confirmAll parameter
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Purge failed
Content-Type: application/json
{
  "error": "string"
}
503Search indexer unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/search/index" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/reindex
Auth required

Trigger fulltext reindex

Starts a fulltext (Meilisearch) reindex operation. Can clear, recreate, or fully reindex.

Request body (application/json)

{}

Responses

200Reindex result
Content-Type: application/json
{
  "ok": true,
  "action": "clear",
  "entityId": null
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
409Reindex already in progress
Content-Type: application/json
{
  "error": "string",
  "lock": {
    "type": "fulltext",
    "action": "string",
    "startedAt": "string",
    "elapsedMinutes": 1,
    "processedCount": null,
    "totalCount": null
  }
}
500Reindex failed
Content-Type: application/json
{
  "error": "string"
}
503Search service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/search/reindex/cancel
Auth required

Cancel fulltext reindex

Cancels an in-progress fulltext reindex operation.

Responses

200Cancel result
Content-Type: application/json
{
  "ok": true,
  "jobsRemoved": 1
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/reindex/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/search/global
Auth required

Global search (Cmd+K)

Performs a global search using saved tenant strategies. Does NOT accept strategies from URL.

Parameters

NameInRequiredSchemaDescription
qqueryYesanySearch query (required)
limitqueryNoanyMaximum results to return (default: 50, max: 100)
entityTypesqueryNoanyComma-separated entity types to filter results (e.g., "customers:customer_person_profile,catalog:catalog_product,sales:sales_order")

Responses

200Search results
Content-Type: application/json
{
  "results": [
    {
      "entityId": "string",
      "recordId": "string",
      "score": 1,
      "source": "fulltext"
    }
  ],
  "strategiesUsed": [
    "fulltext"
  ],
  "strategiesEnabled": [
    "fulltext"
  ],
  "timing": 1,
  "query": "string",
  "limit": 1
}
400Missing query parameter
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Search failed
Content-Type: application/json
{
  "error": "string"
}
503Search service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/search/global?q=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/settings
Auth required

Get search settings and status

Returns search module configuration, available strategies, and reindex lock status.

Responses

200Search settings
Content-Type: application/json
{
  "settings": {
    "strategies": [
      {
        "id": "string",
        "name": "string",
        "priority": 1,
        "available": true
      }
    ],
    "fulltextConfigured": true,
    "fulltextStats": null,
    "vectorConfigured": true,
    "tokensEnabled": true,
    "defaultStrategies": [
      "string"
    ],
    "reindexLock": null,
    "fulltextReindexLock": null,
    "vectorReindexLock": null
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/search/settings/fulltext
Auth required

Get fulltext search configuration

Returns Meilisearch configuration status and index statistics.

Responses

200Fulltext settings
Content-Type: application/json
{
  "driver": null,
  "configured": true,
  "envVars": {
    "MEILISEARCH_HOST": {
      "set": true,
      "hint": "string"
    },
    "MEILISEARCH_API_KEY": {
      "set": true,
      "hint": "string"
    }
  },
  "optionalEnvVars": {
    "MEILISEARCH_INDEX_PREFIX": {
      "set": true,
      "hint": "string"
    },
    "SEARCH_EXCLUDE_ENCRYPTED_FIELDS": {
      "set": true,
      "hint": "string"
    }
  }
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/settings/fulltext" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/search/settings/global-search
Auth required

Update global search strategies

Sets which strategies are enabled for Cmd+K global search.

Request body (application/json)

{
  "enabledStrategies": [
    "fulltext"
  ]
}

Responses

200Updated settings
Content-Type: application/json
{
  "ok": true,
  "enabledStrategies": [
    "fulltext"
  ]
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Internal error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/search/settings/global-search" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"enabledStrategies\": [
    \"fulltext\"
  ]
}"
GET/search/settings/vector-store
Auth required

Get vector store configuration

Returns vector store configuration status.

Responses

200Vector store settings
Content-Type: application/json
{
  "currentDriver": "pgvector",
  "configured": true,
  "drivers": [
    {
      "id": "pgvector",
      "name": "string",
      "configured": true,
      "implemented": true,
      "available": null,
      "unavailableReason": null,
      "envVars": [
        {
          "name": "string",
          "set": true,
          "hint": "string"
        }
      ]
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/search/settings/vector-store" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Feature Toggles

Showing 12 of 12 endpoints
GET/feature_toggles/check/boolean
Auth required

Check if feature is enabled

Checks if a feature toggle is enabled for the current context.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Feature status
Content-Type: application/json
{
  "enabled": true,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/check/boolean?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/json
Auth required

Get json config

Gets the json configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Json config
Content-Type: application/json
{
  "valueType": "json",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/check/json?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/number
Auth required

Get number config

Gets the number configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200Number config
Content-Type: application/json
{
  "valueType": "number",
  "value": 1,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/check/number?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/check/string
Auth required

Get string config

Gets the string configuration for a feature toggle.

Parameters

NameInRequiredSchemaDescription
identifierqueryYesanyFeature toggle identifier

Responses

200String config
Content-Type: application/json
{
  "valueType": "string",
  "value": "string",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
400Bad Request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/check/string?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global
Auth required

List global feature toggles

Returns all global feature toggles with filtering and pagination. Requires superadmin role.

Parameters

NameInRequiredSchemaDescription
pagequeryNoanyPage number for pagination
pageSizequeryNoanyNumber of items per page (max 200)
searchqueryNoanyCase-insensitive search across identifier, name, description, and category
typequeryNoanyFilter by toggle type (boolean, string, number, json)
categoryqueryNoanyFilter by category (case-insensitive partial match)
namequeryNoanyFilter by name (case-insensitive partial match)
identifierqueryNoanyFilter by identifier (case-insensitive partial match)
sortFieldqueryNoanyField to sort by
sortDirqueryNoanySort direction (ascending or descending)

Responses

200Feature toggles collection
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "identifier": "string",
      "name": "string",
      "description": null,
      "category": null,
      "type": "boolean",
      "defaultValue": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - superadmin role required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/global?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/feature_toggles/global
Auth required

Create global feature toggle

Creates a new global feature toggle. Requires superadmin role.

Request body (application/json)

{
  "identifier": "string",
  "name": "string",
  "description": null,
  "category": null,
  "type": "boolean",
  "defaultValue": null
}

Responses

201Feature toggle created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - superadmin role required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/feature_toggles/global" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"identifier\": \"string\",
  \"name\": \"string\",
  \"description\": null,
  \"category\": null,
  \"type\": \"boolean\",
  \"defaultValue\": null
}"
PUT/feature_toggles/global
Auth required

Update global feature toggle

Updates an existing global feature toggle. Requires superadmin role.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "description": null,
  "category": null,
  "defaultValue": null
}

Responses

200Feature toggle updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - superadmin role required
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/feature_toggles/global" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"description\": null,
  \"category\": null,
  \"defaultValue\": null
}"
DELETE/feature_toggles/global
Auth required

Delete global feature toggle

Soft deletes a global feature toggle by ID. Requires superadmin role.

Parameters

NameInRequiredSchemaDescription
idqueryYesanyFeature toggle identifier

Responses

200Feature toggle deleted
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - superadmin role required
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/feature_toggles/global?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}
Auth required

Fetch feature toggle by ID

Returns complete details of a feature toggle.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Feature toggle detail
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "identifier": "string",
  "name": "string",
  "description": null,
  "category": null,
  "type": "boolean",
  "defaultValue": null,
  "createdAt": null,
  "updatedAt": null
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/global/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}/override
Auth required

Fetch feature toggle override

Returns feature toggle override.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Feature toggle overrides
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "tenantName": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "toggleType": "boolean",
  "updatedAt": null
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/global/:id/override" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/overrides
Auth required

List overrides

Returns list of feature toggle overrides.

Parameters

NameInRequiredSchemaDescription
categoryqueryNoany—
namequeryNoany—
identifierqueryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200List of overrides
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "toggleId": "00000000-0000-4000-8000-000000000000",
      "tenantName": "string",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "identifier": "string",
      "name": "string",
      "category": "string",
      "isOverride": true
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "isSuperAdmin": true
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/feature_toggles/overrides?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/feature_toggles/overrides
Auth required

Change override state

Enable, disable or inherit a feature toggle for a specific tenant.

Request body (application/json)

{
  "toggleId": "00000000-0000-4000-8000-000000000000",
  "isOverride": true
}

Responses

200Override updated
Content-Type: application/json
{
  "ok": true,
  "overrideToggleId": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/feature_toggles/overrides" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"toggleId\": \"00000000-0000-4000-8000-000000000000\",
  \"isOverride\": true
}"

Operations

Showing 18 of 18 endpoints
GET/ops/customers
Auth required

List customers

Returns a paginated collection of customers in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
searchqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated customers
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "taxId": null,
      "email": null,
      "phone": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/customers?sortField=name&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/ops/customers
Auth required

Create customer

Creates a customer in the caller tenant and organization scope.

Request body (application/json)

{
  "name": "string",
  "taxId": null,
  "email": null,
  "phone": null
}

Responses

201Customer created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/ops/customers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"taxId\": null,
  \"email\": null,
  \"phone\": null
}"
PUT/ops/customers
Auth required

Update customer

Updates a customer. Send the record `updatedAt` as the optimistic-lock header.

Request body (application/json)

{
  "taxId": null,
  "email": null,
  "phone": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Customer updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/ops/customers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"taxId\": null,
  \"email\": null,
  \"phone\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/ops/customers
Auth required

Delete customer

Soft-deletes a customer by id.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Customer deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/ops/customers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/ops/sites
Auth required

List sites

Returns a paginated collection of sites in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
searchqueryNoany—
customerIdqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated sites
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "customerId": null,
      "addressLine": null,
      "city": null,
      "country": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/sites?sortField=name&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/ops/sites
Auth required

Create site

Creates a site. `customerId` is a scoped soft reference and is validated on write.

Request body (application/json)

{
  "name": "string",
  "customerId": null,
  "addressLine": null,
  "city": null,
  "country": null
}

Responses

201Site created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/ops/sites" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"customerId\": null,
  \"addressLine\": null,
  \"city\": null,
  \"country\": null
}"
PUT/ops/sites
Auth required

Update site

Updates a site. Send the record `updatedAt` as the optimistic-lock header.

Request body (application/json)

{
  "customerId": null,
  "addressLine": null,
  "city": null,
  "country": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Site updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/ops/sites" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"customerId\": null,
  \"addressLine\": null,
  \"city\": null,
  \"country\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/ops/sites
Auth required

Delete site

Soft-deletes a site by id.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Site deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/ops/sites" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/ops/users
Auth required

List assignable operators

Returns selectable users in the caller tenant and organization scope.

Responses

200Assignable operators.
Content-Type: application/json
{
  "items": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/users" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/ops/work-orders
Auth required

List work orders

Returns a paginated collection of work orders in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
searchqueryNoany—
statusqueryNoany—
priorityqueryNoany—
customerIdqueryNoany—
siteIdqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated work orders
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "number": "string",
      "title": "string",
      "description": null,
      "customerId": null,
      "siteId": null,
      "status": "string",
      "priority": "string",
      "scheduledStart": null,
      "scheduledEnd": null,
      "closedAt": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/work-orders?sortField=created_at&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/ops/work-orders
Auth required

Create work order

Creates a work order. The `WO-YYYY-#####` number is allocated server-side and is unique per tenant.

Request body (application/json)

{
  "title": "string",
  "description": null,
  "customerId": null,
  "siteId": null,
  "status": "open",
  "priority": "normal",
  "scheduledStart": null,
  "scheduledEnd": null
}

Responses

201Work Order created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/ops/work-orders" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"title\": \"string\",
  \"description\": null,
  \"customerId\": null,
  \"siteId\": null,
  \"status\": \"open\",
  \"priority\": \"normal\",
  \"scheduledStart\": null,
  \"scheduledEnd\": null
}"
PUT/ops/work-orders
Auth required

Update work order

Updates a work order. `status` is not accepted here — use POST /api/ops/work-orders/{id}/status so the lifecycle transition is validated.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "description": null,
  "customerId": null,
  "siteId": null,
  "scheduledStart": null,
  "scheduledEnd": null
}

Responses

200Work Order updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/ops/work-orders" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"description\": null,
  \"customerId\": null,
  \"siteId\": null,
  \"scheduledStart\": null,
  \"scheduledEnd\": null
}"
DELETE/ops/work-orders
Auth required

Delete work order

Soft-deletes a work order by id.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Work Order deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/ops/work-orders" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/ops/work-orders/{id}/assignees
Auth required

List work order assignees

Returns the operator user ids currently assigned to a work order.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Assigned operators.
Content-Type: application/json
{
  "items": [
    {
      "userId": "00000000-0000-4000-8000-000000000000"
    }
  ]
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Work order not found in scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/work-orders/:id/assignees" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/ops/work-orders/{id}/assignees
Auth required

Replace work order assignees

Replaces the entire assignee set. Idempotent: re-sending the same list converges on the same rows. Send the work order `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "userIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

200Assignees replaced.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "userIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "updatedAt": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Work order not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/ops/work-orders/:id/assignees" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
POST/ops/work-orders/{id}/status
Auth required

Change a work order status

Moves a work order through draft → open → in_progress → done, or to cancelled. Rejects a transition the lifecycle does not allow. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "status": "draft"
}

Responses

200Status applied.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "updatedAt": null
}
400Invalid or disallowed transition
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Work order not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version or unchanged status
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/ops/work-orders/:id/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"status\": \"draft\"
}"
GET/ops/work-orders/assigned
Auth required

List the open work orders the calling operator may work on

Returns open and in-progress work orders in the caller scope: those the caller is assigned to, plus those with no assignees at all.

Responses

200Work orders the operator may pick up.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "number": "string",
      "title": "string",
      "status": "string",
      "priority": "string",
      "customerName": null,
      "siteName": null,
      "scheduledStart": null,
      "assignedToMe": true,
      "startable": true
    }
  ]
}
400Organization scope could not be resolved
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/work-orders/assigned" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/ops/work-orders/by-number
Auth required

Resolve one work order from the number typed or scanned on a terminal

Returns the operator tile for the work order carrying this number in the caller scope, including work orders that are already closed (`startable: false`). A work order the caller may not pick up is reported as not found.

Responses

200The resolved work order.
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "number": "string",
    "title": "string",
    "status": "string",
    "priority": "string",
    "customerName": null,
    "siteName": null,
    "scheduledStart": null,
    "assignedToMe": true,
    "startable": true
  }
}
400Missing number, or unresolvable organization scope
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404No such work order in the caller scope
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/ops/work-orders/by-number" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Time tracking

Showing 11 of 11 endpoints
GET/time/operations
Auth required

List operations

Returns a paginated collection of operations in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
searchqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated operations
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/time/operations?sortField=name&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/time/operations
Auth required

Create operation

Creates an operation label that sessions may reference.

Request body (application/json)

{
  "name": "string"
}

Responses

201Operation created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/operations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/time/operations
Auth required

Update operation

Renames an operation. Send the record `updatedAt` as the optimistic-lock header.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Operation updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/time/operations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/time/operations
Auth required

Delete operation

Soft-deletes an operation. Sessions keep their scalar `operation_id`, so historical labels stay resolvable.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Operation deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/time/operations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/time/sessions
Auth required

List time sessions

Returns a paginated collection of time sessions in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
workOrderIdqueryNoany—
userIdqueryNoany—
statusqueryNoany—
operationIdqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated time sessions
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "workOrderId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "status": "string",
      "startedAt": null,
      "endedAt": null,
      "pauseStartedAt": null,
      "activeSince": null,
      "durationWorkedSeconds": 1,
      "note": null,
      "operationId": null,
      "voided": true,
      "voidReason": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/time/sessions?sortField=started_at&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/time/sessions/{id}/pause
Auth required

Pause a running time session

Freezes the clock: the running segment is banked into `durationWorkedSeconds` and `pauseStartedAt` is set. Only the operator who owns the session may pause it. Send the session `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

200Session paused.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "durationWorkedSeconds": 1,
  "updatedAt": null
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403The session belongs to another operator
Content-Type: application/json
{
  "error": "string"
}
404Session not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or the session is not running
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/sessions/:id/pause" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/time/sessions/{id}/resume
Auth required

Resume a paused time session

Opens a new running segment and clears `pauseStartedAt`. `startedAt` is left untouched — it records when the shift began, not the current segment. Send the session `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

200Session resumed.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "durationWorkedSeconds": 1,
  "updatedAt": null
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403The session belongs to another operator
Content-Type: application/json
{
  "error": "string"
}
404Session not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or the session is not paused
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/sessions/:id/resume" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/time/sessions/{id}/stop
Auth required

Stop a running or paused time session

Finalizes `durationWorkedSeconds`, sets `endedAt`, and frees the operator to start elsewhere. A stopped session can never be deleted — use the void endpoint to correct one. Send the session `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "note": null
}

Responses

200Session stopped.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "durationWorkedSeconds": 1,
  "updatedAt": null
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403The session belongs to another operator
Content-Type: application/json
{
  "error": "string"
}
404Session not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or the session is already stopped
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/sessions/:id/stop" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"note\": null
}"
POST/time/sessions/{id}/void
Auth required

Void a time session with a reason

Excludes the session from every total while keeping the record and the stated reason. A still-open session is stopped first, so a voided record never leaves its operator clocked in. Send the session `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "reason": "string"
}

Responses

200Session voided.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "durationWorkedSeconds": 1,
  "updatedAt": null
}
400A reason is required
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Session not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or the session is already voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/sessions/:id/void" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"reason\": \"string\"
}"
POST/time/sessions/start
Auth required

Start a time session on a work order

Opens a running session for the authenticated operator. Requires an operation from the tenant catalog, the work order to be open or in progress, the operator to be assigned when the work order names assignees, and the operator to have no other running or paused session anywhere in the tenant.

Request body (application/json)

{
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "operationId": "00000000-0000-4000-8000-000000000000",
  "note": null
}

Responses

201Session started.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "status": "string",
  "previousStatus": "string",
  "durationWorkedSeconds": 1,
  "updatedAt": null
}
400Missing or unknown operation, invalid payload, or the work order does not accept sessions
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Time tracking disabled, or the operator is not assigned
Content-Type: application/json
{
  "error": "string"
}
409The operator already has an active session
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/time/sessions/start" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"workOrderId\": \"00000000-0000-4000-8000-000000000000\",
  \"operationId\": \"00000000-0000-4000-8000-000000000000\",
  \"note\": null
}"
GET/time/settings
Auth required

Resolve the tr3.time feature flag

Returns whether time tracking is enabled for the caller tenant.

Responses

200Resolved settings.
Content-Type: application/json
{
  "enabled": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/time/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Workforce

Showing 17 of 17 endpoints
POST/workforce/kiosk/bind

Bind this device to a tenant with an unlock code

Claims a single-use unlock code, creates a kiosk device in the code's tenant and sets the `tr3_kiosk` cookie. Invalid, used, expired and cancelled codes return one identical 400. Failed attempts are rate limited per IP and per browser.

Request body (application/json)

{
  "code": "string"
}

Responses

200Bound.
Content-Type: application/json
{
  "ok": true,
  "deviceLabel": null,
  "tenantName": "string"
}
400Invalid, used, expired or cancelled code (`workforce.errors.unlock_code_invalid`)
Content-Type: application/json
{
  "error": "string"
}
429Too many failed codes
Content-Type: application/json
{
  "error": "workforce.errors.kiosk_locked",
  "retryAfter": 1
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/kiosk/bind" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\"
}"
GET/workforce/kiosk/devices
Auth required

List kiosk devices of the tenant

Live devices plus devices revoked in the last 7 days. Never includes the kiosk token or its hash.

Responses

200Devices.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "label": null,
      "boundAt": null,
      "lastSeenAt": null,
      "lockedUntil": null,
      "revokedAt": null,
      "status": "active"
    }
  ],
  "total": 1,
  "totalPages": 1
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/kiosk/devices" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/workforce/kiosk/devices/{id}
Auth required

Revoke a kiosk device and end its operator sessions

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Revoked.
Content-Type: application/json
{
  "ok": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404No device with that id in this tenant
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/workforce/kiosk/devices/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/workforce/kiosk/status

Whether this device is bound to a tenant

Resolves the `tr3_kiosk` cookie to a live kiosk device. Returns `{ bound: false }` for no, a revoked or an unknown binding (and clears a dead cookie), or the device label, tenant name and current lock expiry. Touches `last_seen_at`.

Responses

200Binding status.
Content-Type: application/json
{
  "bound": false
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/kiosk/status" \
  -H "Accept: application/json"
POST/workforce/kiosk/unbind

Unbind this device from its tenant

Requires the `tr3_kiosk` cookie. Revokes the kiosk device, ends every operator session issued through it and clears the kiosk and session cookies.

Responses

200Unbound.
Content-Type: application/json
{
  "ok": true
}
403No live binding on this device (`workforce.errors.kiosk_unbound`)
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/kiosk/unbind" \
  -H "Accept: application/json"
GET/workforce/kiosk/unlock-codes
Auth required

List pending kiosk unlock codes

Unused, uncancelled and unexpired unlock codes of the tenant. Never includes the code itself.

Responses

200Pending codes.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "label": null,
      "expiresAt": "string",
      "createdAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/kiosk/unlock-codes" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/workforce/kiosk/unlock-codes
Auth required

Generate a kiosk unlock code

Issues a single-use `XXXX-XXXX` code valid for 15 minutes, scoped to the caller's tenant and organization. The plaintext appears only in this response.

Request body (application/json)

{
  "label": null
}

Responses

201Code issued.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "label": null,
  "expiresAt": "string",
  "createdAt": null,
  "code": "string"
}
400Invalid label or no organization context
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/kiosk/unlock-codes" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"label\": null
}"
DELETE/workforce/kiosk/unlock-codes/{id}
Auth required

Cancel an unused kiosk unlock code

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Cancelled.
Content-Type: application/json
{
  "ok": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404No pending code with that id
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/workforce/kiosk/unlock-codes/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/workforce/operator/login

Sign in a production operator with a PIN

Requires a live kiosk binding (`tr3_kiosk` cookie). Resolves the operator by the bound device's tenant and the PIN fingerprint, verifies the bcrypt hash and issues the standard staff session cookies for the operator's backing user. Every wrong-PIN mode returns the same 401 and counts against the device; 5 failures lock the device for 300 seconds.

Request body (application/json)

{
  "pin": "string"
}

Responses

200Signed in.
Content-Type: application/json
{
  "ok": true,
  "redirect": "string",
  "operator": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string"
  }
}
401Unknown PIN, or a deactivated operator
Content-Type: application/json
{
  "error": "string"
}
403This device is not bound to a tenant (`workforce.errors.kiosk_unbound`)
Content-Type: application/json
{
  "error": "string"
}
429Device locked after failed PINs (`workforce.errors.kiosk_locked`, with `retryAfter`), or per-IP rate limit
Content-Type: application/json
{
  "error": "workforce.errors.kiosk_locked",
  "retryAfter": 1
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/operator/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"pin\": \"string\"
}"
POST/workforce/operator/logout

Sign the current operator out of the terminal

Clears the session cookies and revokes the server-side session so a shared tablet is handed over clean. Keeps the `tr3_kiosk` binding cookie.

Responses

200Signed out.
Content-Type: application/json
{
  "ok": true
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/operator/logout" \
  -H "Accept: application/json"
GET/workforce/operator/me
Auth required

Resolve the production operator behind the current session

Requires a live kiosk binding in the session tenant. Returns the operator row linked to the authenticated user, or a null operator id for an office user, plus the device label.

Responses

200Operator identity.
Content-Type: application/json
{
  "operatorId": null,
  "userId": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "code": null,
  "deviceLabel": null
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403No live kiosk binding for the session tenant (`workforce.errors.kiosk_unbound`)
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/operator/me" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/workforce/operators
Auth required

List production operators

Returns a paginated collection of production operators in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—
sortFieldqueryNoany—
searchqueryNoany—
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
activequeryNoany—

Responses

200Paginated production operators
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "code": null,
      "name": "string",
      "active": true,
      "lastLoginAt": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/operators?page=1&pageSize=50&sortDir=asc&sortField=name" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/workforce/operators
Auth required

Create production operator

Creates a production operator. When `userId` is omitted an `auth` user with the `employee` role is provisioned for the operator. The PIN is stored as a bcrypt hash plus a keyed fingerprint and is never returned; it must not already be in use by another operator of the same tenant (409 `workforce.errors.pin_taken`).

Request body (application/json)

{
  "name": "string",
  "pin": "string",
  "userId": null
}

Responses

201Production Operator created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/workforce/operators" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"pin\": \"string\",
  \"userId\": null
}"
PUT/workforce/operators
Auth required

Update production operator

Updates a production operator. Omit `pin` to leave the current PIN unchanged.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Production Operator updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/workforce/operators" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/workforce/operators
Auth required

Delete production operator

Soft-deletes a production operator. The backing user is kept.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Production Operator deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/workforce/operators" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/workforce/settings/work-order-entry-mode
Auth required

Resolve how the terminal asks for a work order

Returns the tenant value of the `tr3.work_order_entry_mode` string toggle: `list`, `type` or `scan`. Falls back to `list` whenever the toggle cannot be resolved.

Responses

200Resolved settings.
Content-Type: application/json
{
  "workOrderEntryMode": "list"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/workforce/settings/work-order-entry-mode" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/workforce/settings/work-order-entry-mode
Auth required

Change the work order entry mode for the caller tenant

Records a per-tenant override on the `tr3.work_order_entry_mode` feature toggle. The tenant is taken from the session, never from the payload.

Request body (application/json)

{
  "workOrderEntryMode": "list"
}

Responses

200Mode changed.
Content-Type: application/json
{
  "workOrderEntryMode": "list"
}
400Invalid mode, or the toggle definition has not been seeded
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing workforce.settings.manage
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/workforce/settings/work-order-entry-mode" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"workOrderEntryMode\": \"list\"
}"

Media

Showing 8 of 8 endpoints
GET/media
Auth required

List media attached to one or more records

Filters by a single `refModule`/`refType`/`refId` triple, by several triples at once through `refs` (comma-separated `module:type:id`), or by explicit `ids`. Voided objects are excluded unless `includeVoided` is set.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoany—
refModulequeryNoany—
refTypequeryNoany—
refIdqueryNoany—
refsqueryNoany—
kindqueryNoany—
rolequeryNoany—
includeVoidedqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Matching media.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "kind": "string",
      "filename": "string",
      "contentType": "string",
      "byteSize": 1,
      "checksum": null,
      "createdByUserId": null,
      "voided": true,
      "createdAt": null,
      "updatedAt": null,
      "links": [
        {
          "refModule": "string",
          "refType": "string",
          "refId": "00000000-0000-4000-8000-000000000000",
          "role": null
        }
      ],
      "contentUrl": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Invalid query
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/media?includeVoided=false&page=1&pageSize=100" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/media/{id}
Auth required

Read one media object

Returns filename, content type, size, checksum and every link the object carries in scope.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200The media object.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "filename": "string",
  "contentType": "string",
  "byteSize": 1,
  "checksum": null,
  "createdByUserId": null,
  "voided": true,
  "createdAt": null,
  "updatedAt": null,
  "links": [
    {
      "refModule": "string",
      "refType": "string",
      "refId": "00000000-0000-4000-8000-000000000000",
      "role": null
    }
  ],
  "contentUrl": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Not found in scope
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/media/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/media/{id}/content

Stream the stored bytes

Serves one media object to a caller holding `media.read`, or to anyone presenting a valid short-lived `token` minted by the signed-url endpoint. Voided objects are refused.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200The stored bytes.
Content-Type: application/json
"string"
401No session and no valid token
Content-Type: application/json
{
  "error": "string"
}
404Not found in scope, or voided
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/media/:id/content" \
  -H "Accept: application/json"
POST/media/{id}/signed-url
Auth required

Create a short-lived download link

Returns a URL valid for 15 minutes that serves this one object without a session.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Signed URL.
Content-Type: application/json
{
  "url": "string",
  "expiresAt": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Not found in scope, or voided
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/media/:id/signed-url" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/media/{id}/void
Auth required

Soft-hide a media object

Marks the object voided: galleries stop listing it and the content route refuses it. The row and the bytes survive — there is no hard delete in the MVP. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

200Object voided.
Content-Type: application/json
{
  "checksum": null,
  "createdByUserId": null,
  "createdAt": null,
  "updatedAt": null
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or already voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/media/:id/void" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/media/links
Auth required

Create a media link

Attaches an existing media object to a record of any module through the polymorphic reference triple. Repeating the same object, reference and role returns the existing link.

Request body (application/json)

{
  "refModule": "string",
  "refType": "string",
  "refId": "00000000-0000-4000-8000-000000000000",
  "mediaId": "00000000-0000-4000-8000-000000000000",
  "role": null
}

Responses

201Link created (or already present).
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "mediaId": "00000000-0000-4000-8000-000000000000",
  "refModule": "string",
  "refType": "string",
  "refId": "00000000-0000-4000-8000-000000000000",
  "role": null,
  "createdAt": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Media is disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}
404Media object not found in scope
Content-Type: application/json
{
  "error": "string"
}
409The media object is voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/media/links" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"refModule\": \"string\",
  \"refType\": \"string\",
  \"refId\": \"00000000-0000-4000-8000-000000000000\",
  \"mediaId\": \"00000000-0000-4000-8000-000000000000\",
  \"role\": null
}"
GET/media/settings
Auth required

Resolve the tr3.media feature flag and upload limits

Returns whether media is enabled for the caller tenant, the maximum upload size and the accepted content types.

Responses

200Resolved settings.
Content-Type: application/json
{
  "enabled": true,
  "maxUploadBytes": 1,
  "acceptedContentTypes": [
    "string"
  ]
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/media/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/media/upload
Auth required

Upload a file, photo or signature PNG

Stores one object (max 20 MB; jpeg, png, webp or pdf) and optionally attaches it to a record in the same request. The caller module is responsible for its own status gates before asking for the upload.

Request body (multipart/form-data)

file=string

Responses

201Media stored.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "filename": "string",
  "contentType": "string",
  "byteSize": 1,
  "checksum": null,
  "createdByUserId": null,
  "voided": true,
  "createdAt": null,
  "updatedAt": null,
  "links": [
    {
      "refModule": "string",
      "refType": "string",
      "refId": "00000000-0000-4000-8000-000000000000",
      "role": null
    }
  ],
  "contentUrl": "string",
  "link": null
}
400Missing file or malformed reference
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Media is disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}
413File exceeds the 20 MB limit
Content-Type: application/json
{
  "error": "string"
}
415Content type is not allow-listed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/media/upload" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: multipart/form-data" \
  -d "{
  \"file\": \"string\"
}"

Forms and reports

Showing 9 of 9 endpoints
GET/forms_reports/settings
Auth required

Resolve the tr3.forms_reports feature flag

Returns whether forms and reports are enabled for the caller tenant.

Responses

200Resolved settings.
Content-Type: application/json
{
  "enabled": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/forms_reports/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/forms_reports/submissions
Auth required

List form submissions

Returns a paginated collection of form submissions in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
workOrderIdqueryNoany—
templateIdqueryNoany—
templateIdsqueryNoany—
qcIssueIdqueryNoany—
submittedByUserIdqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated form submissions
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "workOrderId": "00000000-0000-4000-8000-000000000000",
      "templateId": "00000000-0000-4000-8000-000000000000",
      "qcIssueId": null,
      "templateName": "string",
      "templateSchemaVersion": 1,
      "status": "string",
      "payload": {},
      "submittedByUserId": null,
      "submittedAt": null,
      "pdfMediaId": null,
      "pdfStatus": "string",
      "voided": true,
      "voidReason": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/forms_reports/submissions?sortField=submitted_at&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/forms_reports/submissions/{id}/void
Auth required

Withdraw a filed submission

Marks the submission voided with a mandatory reason. The record and its attachments survive — there is no edit and no delete. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "reason": "string"
}

Responses

200Submission voided.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "templateId": "00000000-0000-4000-8000-000000000000",
  "templateName": "string",
  "templateSchemaVersion": 1,
  "status": "string",
  "pdfStatus": "string",
  "pdfMediaId": null,
  "voided": true,
  "submittedAt": null,
  "updatedAt": null
}
400A reason is required
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Submission not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or already voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/forms_reports/submissions/:id/void" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"reason\": \"string\"
}"
POST/forms_reports/submissions/submit
Auth required

File a form submission against a work order

Requires a work order that is open or in progress, a published template, and a payload that satisfies the template definition frozen at submit time. Photos and signatures are referenced by media id. Submissions cannot be edited afterwards — use the void endpoint to correct one.

Request body (application/json)

{
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "templateId": "00000000-0000-4000-8000-000000000000",
  "qcIssueId": null,
  "payload": {}
}

Responses

201Submission filed.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "templateId": "00000000-0000-4000-8000-000000000000",
  "templateName": "string",
  "templateSchemaVersion": 1,
  "status": "string",
  "pdfStatus": "string",
  "pdfMediaId": null,
  "voided": true,
  "submittedAt": null,
  "updatedAt": null
}
400Invalid payload, work order not accepting submissions, or template not published
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Forms are disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/forms_reports/submissions/submit" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"workOrderId\": \"00000000-0000-4000-8000-000000000000\",
  \"templateId\": \"00000000-0000-4000-8000-000000000000\",
  \"qcIssueId\": null,
  \"payload\": {}
}"
GET/forms_reports/templates
Auth required

List form templates

Returns a paginated collection of form templates in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
searchqueryNoany—
statusqueryNoany—
purposequeryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated form templates
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "description": null,
      "status": "string",
      "purpose": "string",
      "source": "string",
      "schemaVersion": 1,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/forms_reports/templates?sortField=name&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/forms_reports/templates
Auth required

Create form template

Creates a template. New templates start as drafts unless a status is given.

Request body (application/json)

{
  "name": "string",
  "description": null,
  "definition": {
    "sections": [
      {
        "id": "string",
        "title": "string",
        "fields": [
          {
            "id": "string",
            "type": "text",
            "label": "string"
          }
        ]
      }
    ]
  }
}

Responses

201Form Template created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/forms_reports/templates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"description\": null,
  \"definition\": {
    \"sections\": [
      {
        \"id\": \"string\",
        \"title\": \"string\",
        \"fields\": [
          {
            \"id\": \"string\",
            \"type\": \"text\",
            \"label\": \"string\"
          }
        ]
      }
    ]
  }
}"
PUT/forms_reports/templates
Auth required

Update form template

Updates a template, including publish and archive through `status`. Changing `definition` bumps `schemaVersion`, which submissions freeze. Send the record `updatedAt` as the optimistic-lock header.

Request body (application/json)

{
  "description": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Form Template updated
Content-Type: application/json
{
  "ok": true
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/forms_reports/templates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/forms_reports/templates
Auth required

Delete form template

Soft-deletes a template. Submissions keep their scalar `templateId` and their own frozen definition, so filed protocols stay readable.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Form Template deleted
Content-Type: application/json
{
  "ok": true
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/forms_reports/templates" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
POST/forms_reports/templates/import-llm
Auth required

Create a draft template from an uploaded PDF or photo

Reads a PDF or photo already uploaded through the media module and creates a DRAFT form template from it, with `source=llm_import`. The import never publishes: an administrator reviews and publishes the draft. When no model provider is configured the draft is a starter skeleton and `extracted` is false.

Request body (application/json)

{
  "mediaId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Draft template created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "purpose": "string",
  "fieldCount": 1,
  "extracted": true
}
400Invalid payload, unknown document, or unsupported file type
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Forms are disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/forms_reports/templates/import-llm" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"mediaId\": \"00000000-0000-4000-8000-000000000000\"
}"

Quality control

Showing 7 of 7 endpoints
GET/qc/issues
Auth required

List quality issues

Returns a paginated collection of quality issues in the current tenant and organization scope.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).
workOrderIdqueryNoany—
kindqueryNoany—
statusqueryNoany—
severityqueryNoany—
ownerUserIdqueryNoany—
unassignedqueryNoany—
reportedByUserIdqueryNoany—
overduequeryNoany—
includeVoidedqueryNoany—
searchqueryNoany—
sortFieldqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortDirqueryNoany—

Responses

200Paginated quality issues
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "number": "string",
      "workOrderId": "00000000-0000-4000-8000-000000000000",
      "kind": "string",
      "title": "string",
      "description": null,
      "status": "string",
      "severity": "string",
      "reportedByUserId": null,
      "reportedAt": null,
      "ownerUserId": null,
      "dueAt": null,
      "resolutionNote": null,
      "resolvedAt": null,
      "closedAt": null,
      "voided": true,
      "voidReason": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/qc/issues?sortField=reported_at&page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/qc/issues
Auth required

Create quality issue

Reports a non-conformity or a production problem against a work order. The work order must exist in scope and must not be a draft — `done` and `cancelled` are accepted on purpose. Photos are media ids uploaded through `POST /api/media/upload` beforehand.

Request body (application/json)

{
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "kind": "ncr",
  "title": "string",
  "description": null
}

Responses

201Quality Issue created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "number": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/qc/issues" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"workOrderId\": \"00000000-0000-4000-8000-000000000000\",
  \"kind\": \"ncr\",
  \"title\": \"string\",
  \"description\": null
}"
GET/qc/issues/{id}
Auth required

Read one quality issue

Returns the issue, including a voided one so its reason stays inspectable.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200The issue.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "number": "string",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "title": "string",
  "description": null,
  "status": "string",
  "severity": "string",
  "reportedByUserId": null,
  "reportedAt": null,
  "ownerUserId": null,
  "dueAt": null,
  "resolutionNote": null,
  "resolvedAt": null,
  "closedAt": null,
  "voided": true,
  "voidReason": null,
  "createdAt": null,
  "updatedAt": null
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
404Issue not found in scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/qc/issues/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/qc/issues/{id}
Auth required

Triage a quality issue

Sets kind, severity, owner and due date and corrects the text in one write. `kind` stays changeable until the issue is closed. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "ownerUserId": null,
  "dueAt": null,
  "description": null
}

Responses

200Issue triaged.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "number": "string",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "status": "string",
  "severity": "string",
  "ownerUserId": null,
  "dueAt": null,
  "voided": true,
  "updatedAt": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Quality control is disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}
404Issue not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, issue closed, or issue voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/qc/issues/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ownerUserId\": null,
  \"dueAt\": null,
  \"description\": null
}"
POST/qc/issues/{id}/status
Auth required

Move a quality issue through its lifecycle

Moves an issue along open → in_progress → resolved → closed, including the office shortcut open → closed and the reopen closed → in_progress. Entering `resolved`, and the shortcut, require a resolution note. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "status": "open",
  "resolutionNote": null
}

Responses

200Status applied.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "number": "string",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "status": "string",
  "severity": "string",
  "ownerUserId": null,
  "dueAt": null,
  "voided": true,
  "updatedAt": null
}
400Missing owner or resolution note
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403The caller may not make this move, or QC is disabled
Content-Type: application/json
{
  "error": "string"
}
404Issue not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, disallowed transition, unchanged status, or voided issue
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/qc/issues/:id/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"status\": \"open\",
  \"resolutionNote\": null
}"
POST/qc/issues/{id}/void
Auth required

Withdraw a quality issue from the counters

Marks the issue voided with a mandatory reason. The record and its photos survive — there is no delete. Send the record `updatedAt` as the optimistic-lock header.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "reason": "string"
}

Responses

200Issue voided.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "number": "string",
  "workOrderId": "00000000-0000-4000-8000-000000000000",
  "kind": "string",
  "status": "string",
  "severity": "string",
  "ownerUserId": null,
  "dueAt": null,
  "voided": true,
  "updatedAt": null
}
400A reason is required
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Quality control is disabled for this tenant
Content-Type: application/json
{
  "error": "string"
}
404Issue not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Stale version, or already voided
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/qc/issues/:id/void" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"reason\": \"string\"
}"
GET/qc/settings
Auth required

Resolve the tr3.qc feature flag

Returns whether quality control is enabled for the caller tenant, whether forms and reports are enabled, and whether QC checklists are available — which requires both.

Responses

200Resolved settings.
Content-Type: application/json
{
  "enabled": true,
  "formsReportsEnabled": true,
  "checklistsEnabled": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Unexpected server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/qc/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Auth

Showing 1 of 1 endpoints
GET/auth/users/consents
Auth required

List user consents

Returns all consent records for a given user, with integrity verification status.

Parameters

NameInRequiredSchemaDescription
userIdqueryYesany—

Responses

200Consent list returned
Content-Type: application/json
"string"

Example

curl -X GET "https://server.tail3470ec.ts.net/api/auth/users/consents?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Configs

Showing 8 of 8 endpoints
GET/configs/cache
Auth required

Get cache statistics

Returns detailed cache statistics including total entries and breakdown by cache segments. Requires cache service to be available.

Responses

200Cache statistics
Content-Type: application/json
{
  "generatedAt": "string",
  "totalKeys": 1,
  "segments": [
    {
      "segment": "string",
      "resource": null,
      "method": null,
      "path": null,
      "keyCount": 1,
      "keys": [
        "string"
      ]
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to resolve cache stats
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/cache
Auth required

Purge cache

Purges cache entries. Supports two actions: purgeAll (clears entire cache) or purgeSegment (clears specific segment). Returns updated cache statistics after purge.

Request body (application/json)

{
  "action": "purgeAll"
}

Responses

200Cache segment cleared successfully
Content-Type: application/json
{
  "action": "purgeSegment",
  "segment": "string",
  "deleted": 1,
  "stats": {
    "generatedAt": "string",
    "totalKeys": 1,
    "segments": [
      {
        "segment": "string",
        "resource": null,
        "method": null,
        "path": null,
        "keyCount": 1,
        "keys": [
          "string"
        ]
      }
    ]
  }
}
400Invalid request - missing segment identifier for purgeSegment action
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to purge cache
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"purgeAll\"
}"
GET/configs/module-telemetry
Auth required

Get module resource usage telemetry

Returns in-process module resource attribution for API routes, event subscribers, and queue workers.

Responses

200Module resource usage report
Content-Type: application/json
{
  "generatedAt": "string",
  "startedAt": "string",
  "enabled": true,
  "bucketIntervalMs": 1,
  "totals": {
    "modules": 1,
    "operations": 1,
    "calls": 1,
    "errors": 1,
    "totalDurationMs": 1,
    "totalCpuMs": 1,
    "positiveHeapDeltaBytes": 1,
    "positiveRssDeltaBytes": 1
  },
  "thresholds": {
    "p95DurationMs": 1,
    "cpuMs": 1,
    "positiveHeapDeltaBytes": 1,
    "positiveRssDeltaBytes": 1,
    "errors": 1
  },
  "modules": [
    {
      "moduleId": "string",
      "calls": 1,
      "errors": 1,
      "totalDurationMs": 1,
      "p95DurationMs": 1,
      "totalCpuMs": 1,
      "positiveHeapDeltaBytes": 1,
      "positiveRssDeltaBytes": 1,
      "surfaces": [
        {
          "surface": "api",
          "calls": 1,
          "errors": 1,
          "totalDurationMs": 1,
          "p95DurationMs": 1,
          "totalCpuMs": 1,
          "positiveHeapDeltaBytes": 1,
          "positiveRssDeltaBytes": 1
        }
      ],
      "topOperations": [
        {
          "moduleId": "string",
          "surface": "api",
          "operation": "string",
          "resourceId": null,
          "calls": 1,
          "errors": 1,
          "totalDurationMs": 1,
          "maxDurationMs": 1,
          "p95DurationMs": 1,
          "totalCpuUserMs": 1,
          "totalCpuSystemMs": 1,
          "maxCpuMs": 1,
          "totalHeapDeltaBytes": 1,
          "positiveHeapDeltaBytes": 1,
          "maxHeapDeltaBytes": 1,
          "totalRssDeltaBytes": 1,
          "positiveRssDeltaBytes": 1,
          "maxRssDeltaBytes": 1,
          "firstSeenAt": "string",
          "lastSeenAt": "string"
        }
      ],
      "candidateReasons": [
        "string"
      ]
    }
  ],
  "candidates": [
    {
      "moduleId": "string",
      "calls": 1,
      "errors": 1,
      "totalDurationMs": 1,
      "p95DurationMs": 1,
      "totalCpuMs": 1,
      "positiveHeapDeltaBytes": 1,
      "positiveRssDeltaBytes": 1,
      "surfaces": [
        {
          "surface": "api",
          "calls": 1,
          "errors": 1,
          "totalDurationMs": 1,
          "p95DurationMs": 1,
          "totalCpuMs": 1,
          "positiveHeapDeltaBytes": 1,
          "positiveRssDeltaBytes": 1
        }
      ],
      "topOperations": [
        {
          "moduleId": "string",
          "surface": "api",
          "operation": "string",
          "resourceId": null,
          "calls": 1,
          "errors": 1,
          "totalDurationMs": 1,
          "maxDurationMs": 1,
          "p95DurationMs": 1,
          "totalCpuUserMs": 1,
          "totalCpuSystemMs": 1,
          "maxCpuMs": 1,
          "totalHeapDeltaBytes": 1,
          "positiveHeapDeltaBytes": 1,
          "maxHeapDeltaBytes": 1,
          "totalRssDeltaBytes": 1,
          "positiveRssDeltaBytes": 1,
          "maxRssDeltaBytes": 1,
          "firstSeenAt": "string",
          "lastSeenAt": "string"
        }
      ],
      "candidateReasons": [
        "string"
      ]
    }
  ],
  "buckets": [
    {
      "bucketStart": "string",
      "bucketEnd": "string",
      "bucketIntervalMs": 1,
      "stage": "startup",
      "partial": true,
      "totals": {
        "modules": 1,
        "calls": 1,
        "errors": 1,
        "totalDurationMs": 1,
        "totalCpuMs": 1,
        "positiveHeapDeltaBytes": 1,
        "positiveRssDeltaBytes": 1
      },
      "modules": [
        {
          "moduleId": "string",
          "calls": 1,
          "errors": 1,
          "totalDurationMs": 1,
          "p95DurationMs": 1,
          "totalCpuMs": 1,
          "positiveHeapDeltaBytes": 1,
          "positiveRssDeltaBytes": 1,
          "surfaces": [
            {
              "surface": "api",
              "calls": 1,
              "errors": 1,
              "totalDurationMs": 1,
              "p95DurationMs": 1,
              "totalCpuMs": 1,
              "positiveHeapDeltaBytes": 1,
              "positiveRssDeltaBytes": 1
            }
          ],
          "topOperations": [
            {
              "moduleId": "string",
              "surface": "api",
              "operation": "string",
              "resourceId": null,
              "calls": 1,
              "errors": 1,
              "totalDurationMs": 1,
              "maxDurationMs": 1,
              "p95DurationMs": 1,
              "totalCpuUserMs": 1,
              "totalCpuSystemMs": 1,
              "maxCpuMs": 1,
              "totalHeapDeltaBytes": 1,
              "positiveHeapDeltaBytes": 1,
              "maxHeapDeltaBytes": 1,
              "totalRssDeltaBytes": 1,
              "positiveRssDeltaBytes": 1,
              "maxRssDeltaBytes": 1,
              "firstSeenAt": "string",
              "lastSeenAt": "string"
            }
          ],
          "candidateReasons": [
            "string"
          ]
        }
      ]
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/configs/module-telemetry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/configs/module-telemetry
Auth required

Clear module telemetry data

Development-only endpoint that clears in-memory module telemetry and local process telemetry files.

Responses

200Module telemetry cleared
Content-Type: application/json
{
  "cleared": true
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Forbidden outside development mode
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/configs/module-telemetry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/configs/system-status
Auth required

Get system health status

Returns comprehensive system health information including environment details, version, resource usage, and service connectivity status.

Responses

200System status snapshot
Content-Type: application/json
{
  "generatedAt": "string",
  "runtimeMode": "development",
  "categories": [
    {
      "key": "profiling",
      "labelKey": "string",
      "descriptionKey": null,
      "items": [
        {
          "key": "string",
          "category": "profiling",
          "kind": "boolean",
          "labelKey": "string",
          "descriptionKey": "string",
          "docUrl": null,
          "defaultValue": null,
          "state": "enabled",
          "value": null,
          "normalizedValue": null
        }
      ]
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to load system status
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/system-status
Auth required

Clear system cache

Purges the entire cache for the current tenant. Useful for troubleshooting or forcing fresh data loading.

Responses

200Cache cleared successfully
Content-Type: application/json
{
  "cleared": true
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to purge cache
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/configs/upgrade-actions
Auth required

List pending upgrade actions

Returns a list of pending upgrade actions for the current version. These are one-time setup tasks that need to be executed after upgrading to a new version. Requires organization and tenant context.

Responses

200List of pending upgrade actions
Content-Type: application/json
{
  "version": "string",
  "actions": [
    {
      "id": "string",
      "version": "string",
      "message": "string",
      "ctaLabel": "string",
      "successMessage": "string",
      "loadingLabel": "string"
    }
  ]
}
400Missing organization or tenant context
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
500Failed to load upgrade actions
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/upgrade-actions
Auth required

Execute upgrade action

Executes a specific upgrade action by ID. Typically used for one-time setup tasks like seeding example data after version upgrade. Returns execution status and localized success message.

Request body (application/json)

{
  "actionId": "string"
}

Responses

200Upgrade action executed successfully
Content-Type: application/json
{
  "status": "string",
  "message": "string",
  "version": "string"
}
400Invalid request body or missing context
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Upgrade actions are disabled
Content-Type: application/json
{
  "error": "string"
}
500Failed to execute upgrade action
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"actionId\": \"string\"
}"

Dashboards

Showing 10 of 10 endpoints
GET/dashboards/layout
Auth required

Load the current dashboard layout

Returns the saved widget layout together with the widgets the current user is allowed to place.

Responses

200Current dashboard layout and available widgets.
Content-Type: application/json
{
  "layout": {
    "items": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "widgetId": "string",
        "order": 1
      }
    ]
  },
  "allowedWidgetIds": [
    "string"
  ],
  "canConfigure": true,
  "context": {
    "userId": "00000000-0000-4000-8000-000000000000",
    "tenantId": null,
    "organizationId": null,
    "userName": null,
    "userEmail": null,
    "userLabel": "string"
  },
  "widgets": [
    {
      "id": "string",
      "title": "string",
      "description": null,
      "defaultSize": "sm",
      "defaultEnabled": true,
      "defaultSettings": null,
      "features": [
        "string"
      ],
      "moduleId": "string",
      "icon": null,
      "loaderKey": "string",
      "supportsRefresh": true
    }
  ]
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/layout
Auth required

Persist dashboard layout changes

Saves the provided widget ordering, sizes, and settings for the current user.

Request body (application/json)

{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "widgetId": "string",
      "order": 1
    }
  ]
}

Responses

200Layout updated successfully.
Content-Type: application/json
{
  "ok": true
}
400Invalid layout payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing dashboards.configure feature
Content-Type: application/json
{
  "error": "string"
}
503Widget registry unavailable — the layout was not saved
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"items\": [
    {
      \"id\": \"00000000-0000-4000-8000-000000000000\",
      \"widgetId\": \"string\",
      \"order\": 1
    }
  ]
}"
PATCH/dashboards/layout/{itemId}
Auth required

Update a dashboard layout item

Adjusts the size or settings for a single widget within the dashboard layout.

Parameters

NameInRequiredSchemaDescription
itemIdpathYesany—

Request body (application/json)

{}

Responses

200Layout item updated.
Content-Type: application/json
{
  "ok": true
}
400Invalid payload or missing item id
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing dashboards.configure feature
Content-Type: application/json
{
  "error": "string"
}
404Item not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://server.tail3470ec.ts.net/api/dashboards/layout/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
GET/dashboards/roles/widgets
Auth required

Fetch widget assignments for a role

Returns the widgets explicitly assigned to the given role together with the evaluation scope.

Parameters

NameInRequiredSchemaDescription
roleIdqueryYesany—
tenantIdqueryNoany—
organizationIdqueryNoany—

Responses

200Current widget configuration for the role.
Content-Type: application/json
{
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
400Missing role identifier
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions to manage role widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/dashboards/roles/widgets?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/roles/widgets
Auth required

Update widgets assigned to a role

Persists the widget list for a role within the provided tenant and organization scope.

Request body (application/json)

{
  "roleId": "00000000-0000-4000-8000-000000000000",
  "widgetIds": [
    "string"
  ]
}

Responses

200Widgets updated successfully.
Content-Type: application/json
{
  "ok": true,
  "widgetIds": [
    "string"
  ]
}
400Invalid payload or unknown widgets
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions to manage role widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/dashboards/roles/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleId\": \"00000000-0000-4000-8000-000000000000\",
  \"widgetIds\": [
    \"string\"
  ]
}"
GET/dashboards/users/widgets
Auth required

Read widget overrides for a user

Returns the widgets inherited and explicitly configured for the requested user within the current scope.

Parameters

NameInRequiredSchemaDescription
userIdqueryYesany—
tenantIdqueryNoany—
organizationIdqueryNoany—

Responses

200Widget settings for the user.
Content-Type: application/json
{
  "mode": "inherit",
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "effectiveWidgetIds": [
    "string"
  ],
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
400Missing user identifier
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions to manage user widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/dashboards/users/widgets?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/users/widgets
Auth required

Update user-specific dashboard widgets

Sets the widget override mode and allowed widgets for a user. Passing `mode: inherit` clears overrides.

Request body (application/json)

{
  "userId": "00000000-0000-4000-8000-000000000000",
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}

Responses

200Overrides saved.
Content-Type: application/json
{
  "ok": true,
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}
400Invalid payload or unknown widgets
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions to manage user widgets
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/dashboards/users/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\",
  \"mode\": \"inherit\",
  \"widgetIds\": [
    \"string\"
  ]
}"
GET/dashboards/widgets/catalog
Auth required

List available dashboard widgets

Returns the catalog of widgets that modules expose, including defaults and feature requirements.

Responses

200Widgets available for assignment.
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "description": null,
      "defaultSize": "sm",
      "defaultEnabled": true,
      "defaultSettings": null,
      "features": [
        "string"
      ],
      "moduleId": "string",
      "icon": null,
      "loaderKey": "string",
      "supportsRefresh": true
    }
  ]
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Insufficient permissions to view widget catalog
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/dashboards/widgets/catalog" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dashboards/widgets/data
Auth required

Fetch aggregated data for dashboard widgets

Executes an aggregation query against the specified entity type and returns the result. Supports date range filtering, grouping, and period-over-period comparison.

Request body (application/json)

{
  "entityType": "string",
  "metric": {
    "field": "string",
    "aggregate": "count"
  }
}

Responses

200Aggregated data for the widget.
Content-Type: application/json
{
  "value": null,
  "data": [
    {
      "value": null
    }
  ],
  "metadata": {
    "fetchedAt": "string",
    "recordCount": 1,
    "currency": null
  }
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing analytics.view feature
Content-Type: application/json
{
  "error": "string"
}
422Too many rows to group an encrypted field in application code
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}
503Encryption is configured but the group source cannot currently be resolved
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/dashboards/widgets/data" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\",
  \"metric\": {
    \"field\": \"string\",
    \"aggregate\": \"count\"
  }
}"
POST/dashboards/widgets/data/batch
Auth required

Fetch aggregated data for multiple dashboard widgets in one request

Resolves a batch of widget data requests with a single authentication, RBAC, organization-scope, and database-context setup. Each request is keyed by an opaque widget id and resolved independently, so a failure in one widget does not fail the batch.

Request body (application/json)

{
  "requests": [
    {
      "id": "string",
      "request": {
        "entityType": "string",
        "metric": {
          "field": "string",
          "aggregate": "count"
        }
      }
    }
  ]
}

Responses

200Per-widget aggregation results keyed by request id.
Content-Type: application/json
{
  "results": [
    {
      "id": "string",
      "ok": true,
      "data": {
        "value": null,
        "data": [
          {
            "value": null
          }
        ],
        "metadata": {
          "fetchedAt": "string",
          "recordCount": 1,
          "currency": null
        }
      }
    }
  ]
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/dashboards/widgets/data/batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"requests\": [
    {
      \"id\": \"string\",
      \"request\": {
        \"entityType\": \"string\",
        \"metric\": {
          \"field\": \"string\",
          \"aggregate\": \"count\"
        }
      }
    }
  ]
}"

Directory

Showing 11 of 11 endpoints
GET/directory/organization-branding
Auth required

Read sidebar branding for the selected organization

Returns the logo URL used by the backend sidebar for the currently selected organization.

Responses

200Organization branding
Content-Type: application/json
{
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "organizationName": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "logoUrl": null,
  "logoPreserveAspectRatio": true,
  "updatedAt": null
}
400A concrete organization scope is required
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
404Organization not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/organization-branding" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/directory/organization-branding
Auth required

Update sidebar branding for the selected organization

Stores an external image URL or an internal attachment image URL as the selected organization logo.

Request body (application/json)

{
  "logoUrl": null
}

Responses

200Updated organization branding
Content-Type: application/json
{
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "organizationName": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "logoUrl": null,
  "logoPreserveAspectRatio": true,
  "updatedAt": null
}
400Save failed
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
409Organization branding changed since it was loaded
Content-Type: application/json
{
  "error": "string"
}
422Invalid logo URL
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/directory/organization-branding" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"logoUrl\": null
}"
GET/directory/organization-switcher
Auth required

Load organization switcher menu

Returns the hierarchical menu of organizations the current user may switch to within the active tenant.

Responses

200Organization switcher payload.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "depth": 1,
      "selectable": true,
      "children": []
    }
  ],
  "selectedId": null,
  "canManage": true,
  "canViewAllOrganizations": true,
  "tenantId": null,
  "tenants": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true
    }
  ],
  "isSuperAdmin": true
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/organization-switcher" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/directory/organizations
Auth required

List organizations

Returns organizations using options, tree, or paginated manage view depending on the `view` parameter.

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
viewqueryNoany—
idsqueryNoany—
tenantIdqueryNoany—
includeInactivequeryNoany—
statusqueryNoany—

Responses

200Organization data for the requested view.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "parentId": null,
      "parentName": null,
      "tenantId": null,
      "tenantName": null,
      "rootId": null,
      "treePath": null
    }
  ]
}
400Invalid query or tenant scope
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/organizations?page=1&pageSize=50&view=options" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/organizations
Auth required

Create organization

Creates a new organization within a tenant and optionally assigns hierarchy relationships.

Request body (application/json)

{
  "name": "string",
  "slug": null,
  "logoUrl": null,
  "parentId": null
}

Responses

201Organization created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.organizations.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"slug\": null,
  \"logoUrl\": null,
  \"parentId\": null
}"
PUT/directory/organizations
Auth required

Update organization

Updates organization details and hierarchy assignments.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "slug": null,
  "logoUrl": null,
  "parentId": null
}

Responses

200Organization updated.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.organizations.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"slug\": null,
  \"logoUrl\": null,
  \"parentId\": null
}"
DELETE/directory/organizations
Auth required

Delete organization

Soft deletes an organization identified by id.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Organization deleted.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.organizations.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/directory/tenants
Auth required

List tenants

Returns tenants visible to the current user with optional search and pagination.

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
isActivequeryNoany—

Responses

200Paged list of tenants.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Requires super-admin
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/directory/tenants?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/tenants
Auth required

Create tenant

Creates a new tenant and returns its identifier.

Request body (application/json)

{
  "name": "string"
}

Responses

201Tenant created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000"
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.tenants.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/directory/tenants
Auth required

Update tenant

Updates tenant properties such as name or activation state.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Tenant updated.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.tenants.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/directory/tenants
Auth required

Delete tenant

Soft deletes the tenant identified by id.

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Tenant removed.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}
403Missing directory.tenants.manage feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"

Entities

Showing 19 of 19 endpoints
GET/entities/definitions
Auth required

List active custom field definitions

Returns active custom field definitions for the supplied entity ids, respecting tenant scope and tombstones.

Parameters

NameInRequiredSchemaDescription
entityIdqueryNoany—
entityIdsqueryNoany—
fieldsetqueryNoany—

Responses

200Definition list
Content-Type: application/json
{
  "items": [
    {
      "key": "string",
      "kind": "string",
      "label": "string",
      "entityId": "string"
    }
  ]
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions
Auth required

Upsert custom field definition

Creates or updates a custom field definition for the current tenant/org scope.

Request body (application/json)

{
  "entityId": "string",
  "key": "string",
  "kind": "text"
}

Responses

200Definition saved
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "key": "string",
    "kind": "string",
    "configJson": {}
  }
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\",
  \"kind\": \"text\"
}"
DELETE/entities/definitions
Auth required

Soft delete custom field definition

Marks the specified definition inactive and tombstones it for the current scope.

Request body (application/json)

{
  "entityId": "string",
  "key": "string"
}

Responses

200Definition deleted
Content-Type: application/json
{
  "ok": true,
  "version": null
}
400Missing entity id or key
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
POST/entities/definitions.batch
Auth required

Save multiple custom field definitions

Creates or updates multiple definitions for a single entity in one transaction.

Request body (application/json)

{
  "entityId": "string",
  "definitions": [
    {
      "key": "string",
      "kind": "text"
    }
  ]
}

Responses

200Definitions saved
Content-Type: application/json
{
  "ok": true,
  "version": null
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/definitions.batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"definitions\": [
    {
      \"key\": \"string\",
      \"kind\": \"text\"
    }
  ]
}"
GET/entities/definitions.manage
Auth required

Get management snapshot

Returns scoped custom field definitions (including inactive tombstones) for administration interfaces.

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—

Responses

200Scoped definitions and deleted keys
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "key": "string",
      "kind": "string",
      "configJson": null,
      "organizationId": null,
      "tenantId": null
    }
  ],
  "deletedKeys": [
    "string"
  ],
  "version": null
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication or feature
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/definitions.manage?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions.restore
Auth required

Restore definition

Reactivates a previously soft-deleted definition within the current tenant/org scope.

Request body (application/json)

{
  "entityId": "string",
  "key": "string"
}

Responses

200Definition restored
Content-Type: application/json
{
  "ok": true
}
400Missing entity id or key
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/definitions.restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
GET/entities/encryption
Auth required

Fetch encryption map

Returns the encrypted field map for the current tenant/organization scope.

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—

Responses

200Map
Content-Type: application/json
{
  "entityId": "string",
  "fields": [
    {
      "field": "string",
      "hashField": null
    }
  ],
  "updatedAt": null
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/encryption?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/encryption
Auth required

Upsert encryption map

Creates or updates the encryption map for the current tenant/organization scope. Enforces optimistic locking when the caller sends the expected version header.

Request body (application/json)

{
  "entityId": "string",
  "tenantId": null,
  "organizationId": null,
  "fields": [
    {
      "field": "string",
      "hashField": null
    }
  ]
}

Responses

200Saved
Content-Type: application/json
{
  "ok": true,
  "updatedAt": null
}
409Optimistic-lock conflict (stale write)
Content-Type: application/json
{
  "error": "string",
  "code": "string",
  "currentUpdatedAt": "string",
  "expectedUpdatedAt": "string"
}
422Selected organization is unavailable
Content-Type: application/json
{
  "error": "string",
  "code": "organization_selection_invalid"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/encryption" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"tenantId\": null,
  \"organizationId\": null,
  \"fields\": [
    {
      \"field\": \"string\",
      \"hashField\": null
    }
  ]
}"
GET/entities/entities
Auth required

List available entities

Returns generated and custom entities scoped to the caller with field counts per entity.

Responses

200List of entities
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "source": "code",
      "label": "string",
      "count": 1
    }
  ]
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/entities
Auth required

Upsert custom entity

Creates or updates a tenant/org scoped custom entity definition.

Request body (application/json)

{
  "entityId": "string",
  "label": "string",
  "description": null,
  "showInSidebar": false,
  "accessRestricted": false
}

Responses

200Entity saved
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "entityId": "string",
    "label": "string"
  }
}
400Validation error
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"label\": \"string\",
  \"description\": null,
  \"showInSidebar\": false,
  \"accessRestricted\": false
}"
DELETE/entities/entities
Auth required

Soft delete custom entity

Marks the specified custom entity inactive within the current scope.

Request body (application/json)

{
  "entityId": "string"
}

Responses

200Entity deleted
Content-Type: application/json
{
  "ok": true
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
404Entity not found in scope
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\"
}"
GET/entities/entity-settings
Auth required

Get custom entity settings

Returns the tenant-scoped default-restricted policy for new custom entities.

Responses

200Current settings
Content-Type: application/json
{
  "newEntitiesRestrictedByDefault": true,
  "updatedAt": null
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/entity-settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/entities/entity-settings
Auth required

Update custom entity settings

Sets the tenant-scoped default-restricted policy for new custom entities.

Request body (application/json)

{
  "newEntitiesRestrictedByDefault": true
}

Responses

200Updated settings
Content-Type: application/json
{
  "ok": true,
  "newEntitiesRestrictedByDefault": true,
  "updatedAt": null
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
409Optimistic lock conflict
Content-Type: application/json
{
  "code": "string",
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/entities/entity-settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"newEntitiesRestrictedByDefault\": true
}"
GET/entities/records
Auth required

List records

Returns paginated records for the supplied entity. Supports custom field filters, exports, and soft-delete toggles.

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—
pagequeryNoany—
pageSizequeryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
searchqueryNoany—
searchFieldsqueryNoany—
withDeletedqueryNoany—
formatqueryNoany—
exportScopequeryNoany—
export_scopequeryNoany—
allqueryNoany—
fullqueryNoany—

Responses

200Paginated records
Content-Type: application/json
{
  "items": [
    {}
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
400Missing entity id
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/records?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/records
Auth required

Create record

Creates a record for the given entity. When `recordId` is omitted or not a UUID the data engine will generate one automatically.

Request body (application/json)

{
  "entityId": "string",
  "values": {}
}

Responses

200Record created
Content-Type: application/json
{
  "ok": true
}
400Validation failure
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"values\": {}
}"
PUT/entities/records
Auth required

Update record

Updates an existing record. If the provided recordId is not a UUID the record will be created instead to support optimistic flows.

Request body (application/json)

{
  "entityId": "string",
  "recordId": "string",
  "values": {}
}

Responses

200Record updated
Content-Type: application/json
{
  "ok": true
}
400Validation failure
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://server.tail3470ec.ts.net/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"values\": {}
}"
DELETE/entities/records
Auth required

Delete record

Soft deletes the specified record within the current tenant/org scope.

Request body (application/json)

{
  "entityId": "string",
  "recordId": "string"
}

Responses

200Record deleted
Content-Type: application/json
{
  "ok": true
}
400Missing entity id or record id
Content-Type: application/json
{
  "error": "string"
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}
404Record not found
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://server.tail3470ec.ts.net/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\"
}"
GET/entities/relations/options
Auth required

List relation options

Returns up to 200 option entries for populating relation dropdowns, automatically resolving label fields when omitted. An entityId that matches neither an active custom entity nor a registered ORM entity yields an empty option list.

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—
labelFieldqueryNoany—
qqueryNoany—
idsqueryNoany—
routeContextFieldsqueryNoany—

Responses

200Option list
Content-Type: application/json
{
  "items": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/relations/options?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/entities/sidebar-entities
Auth required

Get sidebar entities

Returns custom entities flagged with `showInSidebar` for the current tenant/org scope.

Responses

200Sidebar entities for navigation
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "href": "string"
    }
  ]
}
401Missing authentication
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/entities/sidebar-entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Query Index

Showing 3 of 3 endpoints
POST/query_index/purge
Auth required

Purge query index records

Queues a purge job to remove indexed records for an entity type within the active scope.

Request body (application/json)

{
  "entityType": "string"
}

Responses

200Purge job accepted.
Content-Type: application/json
{
  "ok": true
}
400Missing entity type
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/query_index/purge" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
POST/query_index/reindex
Auth required

Trigger query index rebuild

Queues a reindex job for the specified entity type within the current tenant scope.

Request body (application/json)

{
  "entityType": "string"
}

Responses

200Reindex job accepted.
Content-Type: application/json
{
  "ok": true
}
400Missing entity type
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://server.tail3470ec.ts.net/api/query_index/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
GET/query_index/status
Auth required

Inspect query index coverage

Returns entity counts comparing base tables with the query index along with the latest job status.

Responses

200Current query index status.
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "baseCount": null,
      "indexCount": null,
      "vectorCount": null,
      "fulltextCount": null,
      "ok": true,
      "job": {
        "status": "idle",
        "startedAt": null,
        "finishedAt": null,
        "heartbeatAt": null,
        "processedCount": null,
        "totalCount": null,
        "scope": null
      },
      "refreshedAt": null
    }
  ],
  "errors": [
    {
      "id": "string",
      "source": "string",
      "handler": "string",
      "entityType": null,
      "recordId": null,
      "tenantId": null,
      "organizationId": null,
      "message": "string",
      "stack": null,
      "payload": null,
      "occurredAt": "string"
    }
  ],
  "logs": [
    {
      "id": "string",
      "source": "string",
      "handler": "string",
      "level": "info",
      "entityType": null,
      "recordId": null,
      "tenantId": null,
      "organizationId": null,
      "message": "string",
      "details": null,
      "occurredAt": "string"
    }
  ]
}
400Tenant or organization context required
Content-Type: application/json
{
  "error": "string"
}
401Authentication required
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://server.tail3470ec.ts.net/api/query_index/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"