OpenAPI JSONMarkdown Docs

OpenAPI Explorer

Auto-generated OpenAPI definition for all enabled modules.

Default server: https://portal.gt.freighttech.org/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"
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/auth/feature-check" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
GET/auth/features
Auth requiredauth.acl.manage

List declared feature flags

Returns all static features contributed by the enabled modules along with their module source. Requires features: auth.acl.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/api/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/profile
Auth required

Get current profile

Returns the email address for the signed-in user.

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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 requiredauth.roles.list

List roles

Returns available roles within the current tenant. Super administrators receive visibility across tenants. Requires features: auth.roles.list

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://portal.gt.freighttech.org/api/auth/roles?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/auth/roles
Auth requiredauth.roles.manage

Create role

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

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/auth/roles
Auth requiredauth.roles.manage

Update role

Updates mutable fields on an existing role. Requires features: auth.roles.manage

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"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requiredauth.roles.manage

Delete role

Deletes a role by identifier. Fails when users remain assigned. Requires features: auth.roles.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesanyRole identifier

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/auth/roles?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/auth/roles/acl
Auth requiredauth.acl.manage

Fetch role ACL

Returns the feature and organization assignments associated with a role within the current tenant. Requires features: auth.acl.manage

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"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/auth/roles/acl?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/auth/roles/acl
Auth requiredauth.acl.manage

Update role ACL

Replaces the feature list, super admin flag, and optional organization assignments for a role. Requires features: auth.acl.manage

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"
}
404Role not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/api/version" \
  -H "Accept: application/json"

Audit & Action Logs

Showing 5 of 5 endpoints
GET/audit_logs/audit-logs/access
Auth requiredaudit_logs.view_self

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. Requires features: audit_logs.view_self

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/audit_logs/audit-logs/access" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/audit_logs/audit-logs/actions
Auth requiredaudit_logs.view_self

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. Requires features: audit_logs.view_self

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/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 requiredaudit_logs.view_self

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. Requires features: audit_logs.view_self

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/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 requiredaudit_logs.redo_self

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. Requires features: audit_logs.redo_self

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredaudit_logs.undo_self

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. Requires features: audit_logs.undo_self

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 13 of 13 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
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/notifications?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications
Auth requirednotifications.create

Create notification

Creates a notification for a user. Requires features: notifications.create

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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/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://portal.gt.freighttech.org/api/notifications/:id/restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/batch
Auth requirednotifications.create

POST /notifications/batch

Requires features: notifications.create

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/notifications/batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/feature
Auth requirednotifications.create

POST /notifications/feature

Requires features: notifications.create

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/api/notifications/mark-all-read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/role
Auth requirednotifications.create

POST /notifications/role

Requires features: notifications.create

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/notifications/role" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/settings
Auth requirednotifications.manage

GET /notifications/settings

Requires features: notifications.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/notifications/settings
Auth requirednotifications.manage

POST /notifications/settings

Requires features: notifications.manage

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/notifications/unread-count
Auth required

GET /notifications/unread-count

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/notifications/unread-count" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Events

Showing 2 of 2 endpoints
GET/events
Auth requiredworkflows.view

List declared events

Returns every declared event. Filters: category, module, excludeTriggerExcluded (default true). Requires features: workflows.view

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/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://portal.gt.freighttech.org/api/events/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Attachments

Showing 14 of 14 endpoints
GET/attachments
Auth requiredattachments.view

List attachments for a record

Returns uploaded attachments for the given entity record, ordered by newest first. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesanyEntity identifier that owns the attachments
recordIdqueryYesanyRecord identifier within the entity
pagequeryNoany—
pageSizequeryNoany—

Responses

200Attachments found for the record
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "url": "string",
      "fileName": "string",
      "fileSize": 1,
      "createdAt": "string",
      "mimeType": null,
      "content": null
    }
  ]
}
400Missing entity or record identifiers
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments?entityId=string&recordId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments
Auth requiredattachments.manage

Upload attachment

Uploads a new attachment using multipart form-data and stores metadata for later retrieval. Requires features: attachments.manage

Request body (multipart/form-data)

entityId=string
recordId=string
file=string

Responses

200Attachment stored successfully
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "string",
    "url": "string",
    "fileName": "string",
    "fileSize": 1,
    "content": null
  }
}
400Payload validation error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: multipart/form-data" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"file\": \"string\"
}"
DELETE/attachments
Auth requiredattachments.manage

Delete attachment

Removes an uploaded attachment and deletes the stored asset. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idqueryYesany—

Responses

200Attachment deleted
Content-Type: application/json
{
  "ok": true
}
400Missing attachment identifier
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/attachments?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/file/{id}

Download or serve attachment file

Returns the raw file content for an attachment. Path parameter: {id} - Attachment UUID. Query parameter: ?download=1 - Force file download with Content-Disposition header. Access control is enforced based on partition settings.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File content with appropriate MIME type
Content-Type: application/json
"string"
400Missing attachment ID
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized - authentication required for private partitions
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Attachment or file not found
Content-Type: application/json
{
  "error": "string"
}
500Partition misconfigured
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments/file/:id" \
  -H "Accept: application/json"
GET/attachments/image/{id}/{slug}

Serve image with optional resizing

Returns an image attachment with optional on-the-fly resizing and cropping. Resized images are cached for performance. Only works with image MIME types. Path parameter: {id} - Attachment UUID. Query parameters: ?width=N (1-4000 pixels), ?height=N (1-4000 pixels), ?cropType=cover|contain (resize behavior).

Parameters

NameInRequiredSchemaDescription
idpathYesany—
slugpathNoany—

Responses

200Binary image content (Content-Type: image/jpeg, image/png, etc.)
Content-Type: application/json
"string"
400Invalid parameters, missing ID, or non-image attachment
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized - authentication required for private partitions
Content-Type: application/json
{
  "error": "string"
}
403Forbidden - insufficient permissions
Content-Type: application/json
{
  "error": "string"
}
404Image not found
Content-Type: application/json
{
  "error": "string"
}
500Partition misconfigured or image rendering failed
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments/image/:id/:slug" \
  -H "Accept: application/json"
GET/attachments/library
Auth requiredattachments.view

List attachments

Returns paginated list of attachments with optional filtering by search term, partition, and tags. Includes available tags and partitions. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoanyPage number for pagination
pageSizequeryNoanyNumber of items per page (max 100)
searchqueryNoanySearch by file name (case-insensitive)
partitionqueryNoanyFilter by partition code
tagsqueryNoanyFilter by tags (comma-separated)
sortFieldqueryNoanyField to sort by
sortDirqueryNoanySort direction

Responses

200Attachments list with pagination and metadata
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "fileName": "string",
      "fileSize": 1,
      "mimeType": "string",
      "partitionCode": "string",
      "partitionTitle": null,
      "url": null,
      "createdAt": "string",
      "tags": [
        "string"
      ],
      "assignments": [],
      "content": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "availableTags": [
    "string"
  ],
  "partitions": [
    {
      "code": "string",
      "title": "string",
      "description": null,
      "isPublic": true
    }
  ]
}
400Invalid query parameters
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments/library?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/library/{id}
Auth requiredattachments.view

Get attachment details

Returns complete details of an attachment including metadata, tags, assignments, and custom fields. Requires features: attachments.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Attachment details
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "fileName": "string",
    "fileSize": 1,
    "mimeType": "string",
    "partitionCode": "string",
    "partitionTitle": null,
    "tags": [
      "string"
    ],
    "assignments": [],
    "content": null,
    "customFields": null
  }
}
400Invalid attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/attachments/library/{id}
Auth requiredattachments.manage

Update attachment metadata

Updates attachment tags, assignments, and custom fields. Emits CRUD side effects for indexing and events. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

200Attachment updated successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid payload or attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to save attributes
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
DELETE/attachments/library/{id}
Auth requiredattachments.manage

Delete attachment

Permanently deletes an attachment file from storage and database. Emits CRUD side effects. Requires features: attachments.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Attachment deleted successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid attachment ID
Content-Type: application/json
{
  "error": "string"
}
404Attachment not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/attachments/partitions
Auth requiredattachments.manage

List all attachment partitions

Returns all configured attachment partitions with storage settings, OCR configuration, and access control settings. Requires features: attachments.manage

Responses

200List of partitions
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "title": "string",
      "description": null,
      "isPublic": true,
      "requiresOcr": true,
      "ocrModel": null,
      "configJson": null,
      "createdAt": null,
      "updatedAt": null,
      "envKey": "string"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments/partitions
Auth requiredattachments.manage

Create new partition

Creates a new attachment partition with specified storage and OCR settings. Requires unique partition code. Requires features: attachments.manage

Request body (application/json)

{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null,
  "storageDriver": "local",
  "configJson": null
}

Responses

201Partition created successfully
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "configJson": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
400Invalid payload or partition code
Content-Type: application/json
{
  "error": "string"
}
409Partition code already exists
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null,
  \"storageDriver\": \"local\",
  \"configJson\": null
}"
PUT/attachments/partitions
Auth requiredattachments.manage

Update partition

Updates an existing partition. Partition code cannot be changed. Title, description, OCR settings, and access control can be modified. Requires features: attachments.manage

Request body (application/json)

{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null,
  "storageDriver": "local",
  "configJson": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Partition updated successfully
Content-Type: application/json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "configJson": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
400Invalid payload or code change attempt
Content-Type: application/json
{
  "error": "string"
}
404Partition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null,
  \"storageDriver\": \"local\",
  \"configJson\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/attachments/partitions
Auth requiredattachments.manage

Delete partition

Deletes a partition. Default partitions cannot be deleted. Partitions with existing attachments cannot be deleted. Requires features: attachments.manage

Responses

200Partition deleted successfully
Content-Type: application/json
{
  "ok": true
}
400Invalid ID or default partition deletion attempt
Content-Type: application/json
{
  "error": "string"
}
404Partition not found
Content-Type: application/json
{
  "error": "string"
}
409Partition in use
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/attachments/transfer
Auth requiredattachments.manage

Transfer attachments to different record

Transfers one or more attachments from one record to another within the same entity type. Updates attachment assignments and metadata to reflect the new record. Requires features: attachments.manage

Request body (application/json)

{
  "entityId": "string",
  "attachmentIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "toRecordId": "string"
}

Responses

200Attachments transferred successfully
Content-Type: application/json
{
  "ok": true,
  "updated": 1
}
400Invalid payload
Content-Type: application/json
{
  "error": "string"
}
404Attachments not found
Content-Type: application/json
{
  "error": "string"
}
500Attachment model missing
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/attachments/transfer" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"attachmentIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ],
  \"toRecordId\": \"string\"
}"

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"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/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"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/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"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/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"
}
404Tenant not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/feature_toggles/check/string?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global
Auth requiredfeature_toggles.view

List global feature toggles

Returns all global feature toggles with filtering and pagination. Requires superadmin role. Requires features: feature_toggles.view

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/feature_toggles/global?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/feature_toggles/global
Auth requiredfeature_toggles.global.manage

Create global feature toggle

Creates a new global feature toggle. Requires superadmin role. Requires features: feature_toggles.global.manage

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredfeature_toggles.global.manage

Update global feature toggle

Updates an existing global feature toggle. Requires superadmin role. Requires features: feature_toggles.global.manage

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"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requiredfeature_toggles.global.manage

Delete global feature toggle

Soft deletes a global feature toggle by ID. Requires superadmin role. Requires features: feature_toggles.global.manage

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"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/feature_toggles/global?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}
Auth requiredfeature_toggles.view

Fetch feature toggle by ID

Returns complete details of a feature toggle. Requires features: feature_toggles.view

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"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/feature_toggles/global/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/global/{id}/override
Auth requiredfeature_toggles.view

Fetch feature toggle override

Returns feature toggle override. Requires features: feature_toggles.view

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"
}
404Feature toggle not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/feature_toggles/global/:id/override" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/feature_toggles/overrides
Auth requiredfeature_toggles.view

List overrides

Returns list of feature toggle overrides. Requires features: feature_toggles.view

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/feature_toggles/overrides?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/feature_toggles/overrides
Auth requiredfeature_toggles.manage

Change override state

Enable, disable or inherit a feature toggle for a specific tenant. Requires features: feature_toggles.manage

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"
}
404Not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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
}"

Progress

Showing 6 of 6 endpoints
GET/progress/active
Auth requiredprogress.view

GET /progress/active

Requires features: progress.view

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/progress/active" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/progress/jobs
Auth requiredprogress.view

List progressjobs

Returns a paginated collection of progressjobs scoped to the authenticated tenant. Requires features: progress.view

Parameters

NameInRequiredSchemaDescription
statusqueryNoany—
jobTypequeryNoany—
parentJobIdqueryNoany—
includeCompletedqueryNoany—
completedSincequeryNoany—
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated progressjobs
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "jobType": "string",
      "name": "string",
      "description": null,
      "status": "string",
      "progressPercent": 1,
      "processedCount": 1,
      "totalCount": null,
      "etaSeconds": null,
      "cancellable": true,
      "startedAt": null,
      "finishedAt": null,
      "errorMessage": null,
      "createdAt": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/progress/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/progress/jobs
Auth requiredprogress.create

Create progressjob

Creates a new progress job for tracking a long-running operation. Requires features: progress.create

Request body (application/json)

{
  "jobType": "string",
  "name": "string",
  "cancellable": false
}

Responses

201ProgressJob created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/progress/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"jobType\": \"string\",
  \"name\": \"string\",
  \"cancellable\": false
}"
GET/progress/jobs/{id}
Auth requiredprogress.view

GET /progress/jobs/{id}

Requires features: progress.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/progress/jobs/{id}
Auth requiredprogress.update

PUT /progress/jobs/{id}

Requires features: progress.update

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/progress/jobs/{id}
Auth requiredprogress.cancel

DELETE /progress/jobs/{id}

Requires features: progress.cancel

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

204Success

No response body.

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Integrations

Showing 9 of 9 endpoints
GET/integrations
Auth requiredintegrations.view

List integrations

Returns a paginated collection of integrations. Requires features: integrations.view

Parameters

NameInRequiredSchemaDescription
qqueryNoany—
categoryqueryNoany—
bundleIdqueryNoany—
isEnabledqueryNoany—
healthStatusqueryNoany—
sortqueryNoany—
orderqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated integrations
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "description": null,
      "category": null,
      "tags": [
        "string"
      ],
      "hub": null,
      "providerKey": null,
      "bundleId": null,
      "author": null,
      "company": null,
      "version": null,
      "hasCredentials": true,
      "isEnabled": true,
      "apiVersion": null,
      "healthStatus": "healthy",
      "lastHealthCheckedAt": null,
      "lastHealthLatencyMs": null,
      "enabledAt": null,
      "analytics": {
        "lastActivityAt": null,
        "totalCount": 1,
        "errorCount": 1,
        "errorRate": 1,
        "dailyCounts": [
          1
        ]
      }
    }
  ],
  "total": 1,
  "totalPages": 1,
  "bundles": [
    {
      "id": "string",
      "title": "string",
      "description": "string",
      "icon": null,
      "integrationCount": 1,
      "enabledCount": 1
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/integrations?order=asc&page=1&pageSize=100" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/integrations/{id}
Auth requiredintegrations.view

Get integration detail

Requires features: integrations.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/integrations/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/integrations/{id}/credentials
Auth requiredintegrations.credentials.manage

Get, save, or delete integration credentials

Requires features: integrations.credentials.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/integrations/:id/credentials" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/integrations/{id}/credentials
Auth requiredintegrations.credentials.manage

Get, save, or delete integration credentials

Requires features: integrations.credentials.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/integrations/:id/credentials" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/integrations/{id}/credentials
Auth requiredintegrations.credentials.manage

Get, save, or delete integration credentials

Requires features: integrations.credentials.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

204Success

No response body.

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/integrations/:id/credentials" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/integrations/{id}/health
Auth requiredintegrations.manage

Run health check for an integration

Requires features: integrations.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/integrations/:id/health" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/integrations/{id}/state
Auth requiredintegrations.manage

Update integration state

Requires features: integrations.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/integrations/:id/state" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/integrations/{id}/version
Auth requiredintegrations.manage

Change integration API version

Requires features: integrations.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/integrations/:id/version" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/integrations/logs
Auth requiredintegrations.manage

List integration logs

Requires features: integrations.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/integrations/logs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Scheduler

Showing 8 of 8 endpoints
GET/scheduler/jobs
Auth requiredscheduler.jobs.view

List scheduledjobs

Returns a paginated collection of scheduledjobs scoped to the authenticated organization. Requires features: scheduler.jobs.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
searchqueryNoany—
scopeTypequeryNoany—
isEnabledqueryYesany—
sourceTypequeryNoany—
sourceModulequeryNoany—
sortqueryNoany—
orderqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated scheduledjobs
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "description": null,
      "scopeType": "system",
      "organizationId": null,
      "tenantId": null,
      "scheduleType": "cron",
      "scheduleValue": "string",
      "timezone": "string",
      "targetType": "queue",
      "targetQueue": null,
      "targetCommand": null,
      "targetPayload": null,
      "requireFeature": null,
      "isEnabled": true,
      "lastRunAt": null,
      "nextRunAt": null,
      "sourceType": "user",
      "sourceModule": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/scheduler/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/scheduler/jobs
Auth requiredscheduler.jobs.manage

Create scheduledjob

Creates a new scheduled job with cron or interval-based scheduling. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "name": "string",
  "description": null,
  "scopeType": "system",
  "organizationId": null,
  "tenantId": null,
  "scheduleType": "cron",
  "scheduleValue": "string",
  "timezone": "UTC",
  "targetType": "queue",
  "targetQueue": null,
  "targetCommand": null,
  "targetPayload": null,
  "requireFeature": null,
  "isEnabled": true,
  "sourceType": "user",
  "sourceModule": null
}

Responses

201ScheduledJob created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"description\": null,
  \"scopeType\": \"system\",
  \"organizationId\": null,
  \"tenantId\": null,
  \"scheduleType\": \"cron\",
  \"scheduleValue\": \"string\",
  \"timezone\": \"UTC\",
  \"targetType\": \"queue\",
  \"targetQueue\": null,
  \"targetCommand\": null,
  \"targetPayload\": null,
  \"requireFeature\": null,
  \"isEnabled\": true,
  \"sourceType\": \"user\",
  \"sourceModule\": null
}"
PUT/scheduler/jobs
Auth requiredscheduler.jobs.manage

Update scheduledjob

Updates an existing scheduled job by ID. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "id": "string",
  "description": null,
  "targetQueue": null,
  "targetCommand": null,
  "targetPayload": null,
  "requireFeature": null
}

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\",
  \"description\": null,
  \"targetQueue\": null,
  \"targetCommand\": null,
  \"targetPayload\": null,
  \"requireFeature\": null
}"
DELETE/scheduler/jobs
Auth requiredscheduler.jobs.manage

Delete scheduledjob

Deletes a scheduled job by ID. Requires features: scheduler.jobs.manage

Request body (application/json)

{
  "id": "string"
}

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"
GET/scheduler/jobs/{id}/executions

Get execution history for a schedule

Fetch recent executions from BullMQ for a scheduled job. Requires QUEUE_STRATEGY=async.

Parameters

NameInRequiredSchemaDescription
idpathYesany—
pageSizequeryNoany—

Responses

200Execution history
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "scheduleId": "00000000-0000-4000-8000-000000000000",
      "startedAt": "string",
      "finishedAt": null,
      "status": "running",
      "triggerType": "scheduled",
      "triggeredByUserId": null,
      "errorMessage": null,
      "errorStack": null,
      "durationMs": null,
      "queueJobId": "string",
      "queueName": "string",
      "attemptsMade": 1,
      "result": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1
}
400Local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Schedule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/scheduler/jobs/:id/executions?pageSize=20" \
  -H "Accept: application/json"
GET/scheduler/queue-jobs/{jobId}

Get BullMQ job details and logs

Fetch detailed information and logs for a queue job. Requires QUEUE_STRATEGY=async.

Parameters

NameInRequiredSchemaDescription
jobIdpathYesany—
queuequeryYesany—

Responses

200Job details and logs
Content-Type: application/json
{
  "id": "string",
  "name": "string",
  "state": "waiting",
  "progress": null,
  "returnvalue": null,
  "failedReason": null,
  "stacktrace": null,
  "attemptsMade": 1,
  "processedOn": null,
  "finishedOn": null,
  "logs": [
    "string"
  ]
}
400Invalid request or local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Job not found
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/scheduler/queue-jobs/:jobId?queue=string" \
  -H "Accept: application/json"
GET/scheduler/targets

List available queues and commands

Returns all registered queue names (from module workers) and command IDs (from the command registry) that can be used as schedule targets.

Responses

200Available targets
Content-Type: application/json
{
  "queues": [
    {
      "value": "string",
      "label": "string"
    }
  ],
  "commands": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/scheduler/targets" \
  -H "Accept: application/json"
POST/scheduler/trigger

Manually trigger a schedule

Executes a scheduled job immediately, bypassing the scheduled time. Only works with async queue strategy.

Request body (application/json)

{
  "id": "string"
}

Responses

200Schedule triggered successfully
Content-Type: application/json
{
  "ok": true,
  "jobId": "string",
  "message": "string"
}
400Invalid request or local strategy not supported
Content-Type: application/json
{
  "error": "string"
}
401Unauthorized
Content-Type: application/json
{
  "error": "string"
}
403Access denied
Content-Type: application/json
{
  "error": "string"
}
404Schedule not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/scheduler/trigger" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"

Customer Relationship Management

Showing 2 of 2 endpoints
POST/customers/deals/bulk-update-owner
Auth requiredcustomers.deals.manage

Bulk reassign deal owner

Queues a background job that reassigns the listed deals to a new owner (or clears the owner when null). Requires features: customers.deals.manage

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/deals/bulk-update-owner" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customers/deals/bulk-update-stage
Auth requiredcustomers.deals.manage

Bulk update deal pipeline stage

Queues a background job that moves the listed deals to the same pipeline stage. Returns a progress job id to poll for completion. Requires features: customers.deals.manage

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/deals/bulk-update-stage" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Customer Portal

Showing 19 of 19 endpoints
GET/customer_accounts/portal/events/stream

Subscribe to portal events via SSE (Portal Event Bridge)

Long-lived SSE connection that receives server-side events marked with portalBroadcast: true. Events are filtered by the customer's tenant, organization, and recipient user audience.

Responses

200Event stream (text/event-stream)
Content-Type: application/json
"string"
401Not authenticated
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/events/stream" \
  -H "Accept: application/json"
POST/customer_accounts/portal/feature-check

Check customer portal feature access

Checks which of the requested features the authenticated customer user has. Used by portal menu injection for feature-gating.

Request body (application/json)

{
  "features": [
    "string"
  ]
}

Responses

200Feature check result
Content-Type: application/json
{
  "ok": true,
  "granted": [
    "string"
  ]
}
400Invalid request
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/portal/feature-check" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
POST/customer_accounts/portal/logout

Customer logout

Revokes the current session and clears authentication cookies.

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/portal/logout" \
  -H "Accept: application/json"
GET/customer_accounts/portal/nav

Portal sidebar navigation

Returns the portal sidebar for the authenticated customer. Items are derived from each portal page's `nav` metadata and filtered by `requireCustomerFeatures` against the customer's grants (wildcards honored).

Responses

200Portal sidebar groups
Content-Type: application/json
{
  "ok": true,
  "orgSlug": "string",
  "groups": [
    {
      "id": "main",
      "items": [
        {
          "id": "string",
          "label": "string",
          "href": "string",
          "order": 1
        }
      ]
    }
  ],
  "grantedFeatures": [
    "string"
  ],
  "isPortalAdmin": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Organization not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/nav" \
  -H "Accept: application/json"
GET/customer_accounts/portal/notifications

List customer notifications

Returns paginated notifications for the authenticated customer user. Dismissed notifications are excluded by default unless ?status=dismissed is specified.

Responses

200Notification list
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "type": "string",
      "title": "string",
      "body": null,
      "titleKey": null,
      "bodyKey": null,
      "titleVariables": null,
      "bodyVariables": null,
      "icon": null,
      "severity": "info",
      "status": "unread",
      "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
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/notifications" \
  -H "Accept: application/json"
PUT/customer_accounts/portal/notifications/{id}/dismiss

Dismiss notification

Dismisses a single notification for the authenticated customer user.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Notification dismissed
Content-Type: application/json
{
  "ok": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Notification not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/portal/notifications/00000000-0000-4000-8000-000000000000/dismiss" \
  -H "Accept: application/json"
PUT/customer_accounts/portal/notifications/{id}/read

Mark notification as read

Marks a single notification as read for the authenticated customer user.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Notification marked as read
Content-Type: application/json
{
  "ok": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Notification not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/portal/notifications/00000000-0000-4000-8000-000000000000/read" \
  -H "Accept: application/json"
PUT/customer_accounts/portal/notifications/mark-all-read

Mark all notifications as read

Marks all unread notifications as read for the authenticated customer user.

Responses

200All notifications marked as read
Content-Type: application/json
{
  "ok": true,
  "count": 1
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/portal/notifications/mark-all-read" \
  -H "Accept: application/json"
GET/customer_accounts/portal/notifications/unread-count

Get unread notification count

Returns the number of unread notifications for the authenticated customer user.

Responses

200Unread count
Content-Type: application/json
{
  "ok": true,
  "unreadCount": 1
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/notifications/unread-count" \
  -H "Accept: application/json"
POST/customer_accounts/portal/password-change

Change customer password

Changes the authenticated customer user password after verifying the current password. Revokes all existing sessions.

Request body (application/json)

{
  "currentPassword": "string",
  "newPassword": "string"
}

Responses

200Password changed
Content-Type: application/json
{
  "ok": true
}
400Current password incorrect or validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/portal/password-change" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"currentPassword\": \"string\",
  \"newPassword\": \"string\"
}"
GET/customer_accounts/portal/profile

Get customer profile

Returns the authenticated customer user profile with roles and permissions.

Responses

200Profile data
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string",
    "emailVerified": true,
    "customerEntityId": null,
    "personEntityId": null,
    "isActive": true,
    "lastLoginAt": null,
    "createdAt": "string"
  },
  "roles": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "slug": "string"
    }
  ],
  "resolvedFeatures": [
    "string"
  ],
  "isPortalAdmin": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/profile" \
  -H "Accept: application/json"
PUT/customer_accounts/portal/profile

Update customer profile

Updates the authenticated customer user profile.

Request body (application/json)

{}

Responses

200Profile updated
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string"
  }
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/portal/profile" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{}"
GET/customer_accounts/portal/sessions

List customer sessions

Returns active sessions for the authenticated customer user.

Responses

200Session list
Content-Type: application/json
{
  "ok": true,
  "sessions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ipAddress": null,
      "userAgent": null,
      "lastUsedAt": null,
      "createdAt": "string",
      "expiresAt": "string",
      "isCurrent": true
    }
  ]
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/sessions" \
  -H "Accept: application/json"
POST/customer_accounts/portal/sessions-refresh

Refresh customer JWT from session token

Uses the session cookie to issue a fresh JWT access token.

Responses

200Token refreshed
Content-Type: application/json
{
  "ok": true,
  "resolvedFeatures": [
    "string"
  ]
}
401Invalid session
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/portal/sessions-refresh" \
  -H "Accept: application/json"
DELETE/customer_accounts/portal/sessions/{id}

Revoke a customer session

Revokes a specific session (not the current one).

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Session revoked
Content-Type: application/json
{
  "ok": true
}
400Cannot revoke current session
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Session not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customer_accounts/portal/sessions/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
GET/customer_accounts/portal/users

List company portal users

Lists portal users associated with the same company. Paginated (default pageSize 25, max 100).

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—

Responses

200Paginated user list
Content-Type: application/json
{
  "ok": true,
  "users": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "email": "string",
      "displayName": "string",
      "emailVerified": true,
      "isActive": true,
      "lastLoginAt": null,
      "createdAt": "string",
      "roles": [
        {
          "id": "00000000-0000-4000-8000-000000000000",
          "name": "string",
          "slug": "string"
        }
      ]
    }
  ],
  "total": 1,
  "totalPages": 1,
  "page": 1,
  "pageSize": 1
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/portal/users" \
  -H "Accept: application/json"
POST/customer_accounts/portal/users-invite

Invite a user to the company portal

Creates an invitation for a new user to join the company portal.

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invitation created
Content-Type: application/json
{
  "ok": true,
  "invitation": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "expiresAt": "string"
  }
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions or non-assignable role
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many invitation requests
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/portal/users-invite" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
DELETE/customer_accounts/portal/users/{id}

Delete a company portal user

Soft deletes a portal user and revokes all their sessions.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200User deleted
Content-Type: application/json
{
  "ok": true
}
400Cannot delete self
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customer_accounts/portal/users/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
PUT/customer_accounts/portal/users/{id}/roles

Update portal user roles

Assigns new roles to a company portal user.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

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

Responses

200Roles updated
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/portal/users/00000000-0000-4000-8000-000000000000/roles" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"

ONE Record

Showing 20 of 44 endpoints
GET/gt_peers/one-record/logistics-objects

List Logistics Objects (type, changedSince, cursor, limit ≤ 100); scoped by the peer's grants or the staff feature

Responses

200OK
Content-Type: application/json
"string"
401Unauthorized
Content-Type: application/json
"string"
403Staff session without the type feature
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects" \
  -H "Accept: application/json"
GET/gt_peers/one-record/logistics-objects/{id}

Logistics Object (JSON-LD); ONE Record peer token or staff session, checked in-handler

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id" \
  -H "Accept: application/json"
PATCH/gt_peers/one-record/logistics-objects/{id}

ChangeRequest on a Logistics Object (inbound writes are disabled on the portal → 403)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id" \
  -H "Accept: application/json"
GET/gt_peers/one-record/logistics-objects/{id}/audit-trail
Auth requiredone_record.objects.view

Audit trail of an LO (staff only, unchanged)

Requires features: one_record.objects.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id/audit-trail" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_peers/one-record/logistics-objects/{id}/content

Binary content of a document LO (in-handler ONE Record authz)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id/content" \
  -H "Accept: application/json"
GET/gt_peers/one-record/logistics-objects/{id}/logistics-events

Logistics events of an LO (in-handler ONE Record authz)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id/logistics-events" \
  -H "Accept: application/json"
GET/gt_peers/one-record/logistics-objects/{id}/logistics-events/{eventId}

One logistics event of an LO (in-handler ONE Record authz)

Parameters

NameInRequiredSchemaDescription
idpathYesany—
eventIdpathYesany—

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/logistics-objects/:id/logistics-events/:eventId" \
  -H "Accept: application/json"
GET/gt_peers/one-record/oauth/jwks

JWKS of the ONE Record M2M issuer

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/oauth/jwks" \
  -H "Accept: application/json"
GET/gt_peers/one-record/oauth/metadata

Discovery document of the ONE Record M2M issuer

Responses

200OK
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/one-record/oauth/metadata" \
  -H "Accept: application/json"
POST/gt_peers/one-record/oauth/token

OAuth2 client_credentials token (ONE Record M2M issuer); rate limited per IP and per client_id + IP

Responses

200OK
Content-Type: application/json
"string"
429Too many token requests
Content-Type: application/json
"string"

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_peers/one-record/oauth/token" \
  -H "Accept: application/json"
GET/one_record/access-delegations
Auth requiredone_record.access_grants.manage

GET /one_record/access-delegations

Requires features: one_record.access_grants.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/one_record/access-delegations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/one_record/access-delegations
Auth requiredone_record.access_grants.manage

POST /one_record/access-delegations

Requires features: one_record.access_grants.manage

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/one_record/access-delegations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/one_record/access-delegations/{id}
Auth requiredone_record.access_grants.manage

PUT /one_record/access-delegations/{id}

Requires features: one_record.access_grants.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/one_record/access-delegations/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/one_record/access-delegations/{id}
Auth requiredone_record.access_grants.manage

PATCH /one_record/access-delegations/{id}

Requires features: one_record.access_grants.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/one_record/access-delegations/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/one_record/action-requests/{id}

GET /one_record/action-requests/{id}

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/one_record/action-requests/:id" \
  -H "Accept: application/json"
PATCH/one_record/action-requests/{id}
Auth requiredone_record.objects.publish

PATCH /one_record/action-requests/{id}

Requires features: one_record.objects.publish

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

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

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/one_record/action-requests/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/one_record/action-requests/{id}
Auth requiredone_record.objects.publish

DELETE /one_record/action-requests/{id}

Requires features: one_record.objects.publish

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

204Success

No response body.

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/one_record/action-requests/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/one_record/config
Auth requiredone_record.settings.manage

GET /one_record/config

Requires features: one_record.settings.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/one_record/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/one_record/config
Auth requiredone_record.settings.manage

PUT /one_record/config

Requires features: one_record.settings.manage

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/one_record/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/one_record/deliveries
Auth requiredone_record.subscriptions.manage

GET /one_record/deliveries

Requires features: one_record.subscriptions.manage

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/one_record/deliveries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Auth

Showing 1 of 1 endpoints
GET/auth/users/consents
Auth requiredauth.users.edit

List user consents

Returns all consent records for a given user, with integrity verification status. Requires features: auth.users.edit

Parameters

NameInRequiredSchemaDescription
userIdqueryYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/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 requiredconfigs.cache.view

Get cache statistics

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

Responses

200Cache statistics
Content-Type: application/json
{
  "generatedAt": "string",
  "totalKeys": 1,
  "segments": [
    {
      "segment": "string",
      "resource": null,
      "method": null,
      "path": null,
      "keyCount": 1,
      "keys": [
        "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://portal.gt.freighttech.org/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/cache
Auth requiredconfigs.cache.manage

Purge cache

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

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"
}
500Failed to purge cache
Content-Type: application/json
{
  "error": "string"
}
503Cache service unavailable
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"purgeAll\"
}"
GET/configs/module-telemetry
Auth requiredconfigs.system_status.view

Get module resource usage telemetry

Returns in-process module resource attribution for API routes, event subscribers, and queue workers. Requires features: configs.system_status.view

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"
          ]
        }
      ]
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/configs/module-telemetry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/configs/module-telemetry
Auth requiredconfigs.manage

Clear module telemetry data

Development-only endpoint that clears in-memory module telemetry and local process telemetry files. Requires features: configs.manage

Responses

200Module telemetry cleared
Content-Type: application/json
{
  "cleared": true
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/configs/module-telemetry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/configs/system-status
Auth requiredconfigs.system_status.view

Get system health status

Returns comprehensive system health information including environment details, version, resource usage, and service connectivity status. Requires features: configs.system_status.view

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
        }
      ]
    }
  ]
}
500Failed to load system status
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/system-status
Auth requiredconfigs.manage

Clear system cache

Purges the entire cache for the current tenant. Useful for troubleshooting or forcing fresh data loading. Requires features: configs.manage

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/configs/upgrade-actions
Auth requiredconfigs.manage

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. Requires features: configs.manage

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"
}
500Failed to load upgrade actions
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/configs/upgrade-actions
Auth requiredconfigs.manage

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. Requires features: configs.manage

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"
}
500Failed to execute upgrade action
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"actionId\": \"string\"
}"

CustomerAccounts

Showing 8 of 8 endpoints
GET/customer_accounts/admin/domain-mappings
Auth requiredcustomer_accounts.domain.manage

List domain mappings

Returns all custom-domain mappings for the current tenant, optionally filtered by organization. Requires features: customer_accounts.domain.manage

Responses

200OK
Content-Type: application/json
{
  "ok": true,
  "domainMappings": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "hostname": "string",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "provider": "traefik",
      "status": "pending",
      "verifiedAt": null,
      "lastDnsCheckAt": null,
      "dnsFailureReason": null,
      "tlsFailureReason": null,
      "tlsRetryCount": 1,
      "cnameTarget": null,
      "aRecordTarget": null,
      "createdAt": "string",
      "updatedAt": null
    }
  ],
  "config": {
    "cnameTarget": null,
    "aRecordTarget": null
  }
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/admin/domain-mappings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customer_accounts/admin/domain-mappings
Auth requiredcustomer_accounts.domain.manage

Register a custom domain

Registers a new custom domain mapping for an organization. Verifies via DNS asynchronously. Requires features: customer_accounts.domain.manage

Request body (application/json)

{
  "hostname": "string",
  "organizationId": "00000000-0000-4000-8000-000000000000"
}

Responses

201Created
Content-Type: application/json
{
  "ok": true,
  "domainMapping": {
    "id": "00000000-0000-4000-8000-000000000000",
    "hostname": "string",
    "organizationId": "00000000-0000-4000-8000-000000000000",
    "tenantId": "00000000-0000-4000-8000-000000000000",
    "provider": "traefik",
    "status": "pending",
    "verifiedAt": null,
    "lastDnsCheckAt": null,
    "dnsFailureReason": null,
    "tlsFailureReason": null,
    "tlsRetryCount": 1,
    "cnameTarget": null,
    "aRecordTarget": null,
    "createdAt": "string",
    "updatedAt": null
  }
}
400Validation error
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Conflict
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/domain-mappings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"hostname\": \"string\",
  \"organizationId\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/customer_accounts/admin/domain-mappings
Auth requiredcustomer_accounts.domain.manage

Remove a custom domain

Removes the domain mapping identified by ?id=. Cache and Traefik routing drain within TTL. Requires features: customer_accounts.domain.manage

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
400Bad request
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customer_accounts/admin/domain-mappings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customer_accounts/admin/domain-mappings/{id}/health-check
Auth requiredcustomer_accounts.domain.manage

Trigger TLS health check

Runs an HTTPS probe to verify Traefik has provisioned a certificate. On success: transitions the mapping to active. Requires features: customer_accounts.domain.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
{
  "ok": true,
  "domainMapping": {
    "id": "00000000-0000-4000-8000-000000000000",
    "hostname": "string",
    "status": "string",
    "tlsRetryCount": 1,
    "tlsFailureReason": null
  }
}
404Not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/domain-mappings/:id/health-check" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customer_accounts/admin/domain-mappings/{id}/verify
Auth requiredcustomer_accounts.domain.manage

Trigger DNS verification

Runs DNS verification (CNAME → A → reverse-resolve fallback) for the domain mapping. Returns diagnostics on failure. Requires features: customer_accounts.domain.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK — see status
Content-Type: application/json
{
  "ok": true,
  "domainMapping": {
    "id": "00000000-0000-4000-8000-000000000000",
    "hostname": "string",
    "status": "string",
    "verifiedAt": null,
    "lastDnsCheckAt": null,
    "dnsFailureReason": null
  },
  "diagnostics": null
}
404Not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/domain-mappings/:id/verify" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/customer_accounts/domain-check

Verify a hostname is allowed for TLS provisioning

Called by Traefik before issuing a Let's Encrypt certificate. Requires the X-Domain-Check-Secret header to match DOMAIN_CHECK_SECRET.

Responses

200Hostname allowed
Content-Type: application/json
{
  "ok": true
}
403Forbidden
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Hostname not registered or not yet verified
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
503Server misconfiguration
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/domain-check" \
  -H "Accept: application/json"
GET/customer_accounts/domain-resolve

Single-host resolve for the Node middleware

Internal endpoint used by the portal middleware to populate its in-memory cache. Requires X-Domain-Resolve-Secret header.

Responses

200OK
Content-Type: application/json
{
  "ok": true,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "orgSlug": null,
  "status": "active"
}
400Bad request
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Forbidden
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
503Server misconfiguration
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/domain-resolve" \
  -H "Accept: application/json"
GET/customer_accounts/domain-resolve/all

Batch warm-up for the Node middleware

Returns every active domain mapping in a single payload so the middleware can populate its cache on process start. Requires X-Domain-Resolve-Secret header.

Responses

200OK
Content-Type: application/json
{
  "ok": true,
  "domains": [
    {
      "hostname": "string",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "orgSlug": null,
      "status": "active"
    }
  ]
}
403Forbidden
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many requests
Content-Type: application/json
{
  "error": "string"
}
503Server misconfiguration
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/domain-resolve/all" \
  -H "Accept: application/json"

Customer Accounts Admin

Showing 15 of 15 endpoints
GET/customer_accounts/admin/roles

List customer roles (admin)

Returns all customer roles for the tenant.

Responses

200Role list
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "slug": "string",
      "description": null,
      "isDefault": true,
      "isSystem": true,
      "customerAssignable": true,
      "createdAt": "string",
      "updatedAt": null
    }
  ],
  "total": 1,
  "totalPages": 1,
  "page": 1
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles" \
  -H "Accept: application/json"
POST/customer_accounts/admin/roles

Create customer role (admin)

Creates a new customer role with an empty ACL.

Request body (application/json)

{
  "name": "string",
  "slug": "string"
}

Responses

201Role created
Content-Type: application/json
{
  "ok": true,
  "role": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "slug": "string",
    "description": null,
    "isDefault": true,
    "isSystem": true,
    "customerAssignable": true,
    "createdAt": "string"
  }
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Slug already exists
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"slug\": \"string\"
}"
GET/customer_accounts/admin/roles/{id}

Get customer role detail (admin)

Returns full customer role details including ACL features.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Role detail with ACL
Content-Type: application/json
{
  "ok": true,
  "role": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "slug": "string",
    "description": null,
    "isDefault": true,
    "isSystem": true,
    "customerAssignable": true,
    "createdAt": "string",
    "updatedAt": null,
    "acl": {
      "features": [
        "string"
      ],
      "isPortalAdmin": true
    }
  }
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
PUT/customer_accounts/admin/roles/{id}

Update customer role (admin)

Updates a customer role. System roles are protected from name changes.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

200Role updated
Content-Type: application/json
{
  "ok": true
}
400Validation failed or system role restriction
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{}"
DELETE/customer_accounts/admin/roles/{id}

Delete customer role (admin)

Soft deletes a customer role and its ACL. The default role (auto-assigned to new portal users) and roles with assigned users cannot be deleted.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Role deleted
Content-Type: application/json
{
  "ok": true
}
400Default role or has assigned users
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
PUT/customer_accounts/admin/roles/{id}/acl

Update customer role ACL (admin)

Updates the ACL (features and portal admin flag) for a customer role. Invalidates RBAC cache after update.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "features": [
    "string"
  ]
}

Responses

200ACL updated
Content-Type: application/json
{
  "ok": true,
  "updatedAt": "string"
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Role not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Stale ACL write (optimistic-lock conflict)
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000/acl" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
GET/customer_accounts/admin/users

List customer users (admin)

Returns a paginated list of customer users with roles. Supports filtering by status, company, role, and search.

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
statusqueryNoany—
customerEntityIdqueryNoany—
roleIdqueryNoany—
searchqueryNoany—

Responses

200Paginated user list
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "email": "string",
      "displayName": "string",
      "emailVerified": true,
      "isActive": true,
      "lockedUntil": null,
      "lastLoginAt": null,
      "customerEntityId": null,
      "personEntityId": null,
      "createdAt": "string",
      "updatedAt": null,
      "roles": [
        {
          "id": "00000000-0000-4000-8000-000000000000",
          "name": "string",
          "slug": "string"
        }
      ]
    }
  ],
  "total": 1,
  "totalPages": 1,
  "page": 1
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/admin/users" \
  -H "Accept: application/json"
POST/customer_accounts/admin/users

Create customer user (admin)

Creates a new customer user directly. Staff-initiated, bypasses signup flow.

Request body (application/json)

{
  "email": "user@example.com",
  "password": "string",
  "displayName": "string"
}

Responses

201User created
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string"
  }
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Email already exists
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/users" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\",
  \"displayName\": \"string\"
}"
POST/customer_accounts/admin/users-invite

Invite customer user (admin)

Creates a staff-initiated invitation for a new customer user. The invitedByUserId is set from the staff auth context.

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invitation created
Content-Type: application/json
{
  "ok": true,
  "invitation": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "expiresAt": "string"
  }
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many invitation requests
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/users-invite" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
GET/customer_accounts/admin/users/{id}

Get customer user detail (admin)

Returns full customer user details including CRM links, roles, and active session count.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200User detail
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string",
    "emailVerified": true,
    "isActive": true,
    "lockedUntil": null,
    "lastLoginAt": null,
    "failedLoginAttempts": 1,
    "customerEntityId": null,
    "personEntityId": null,
    "createdAt": "string",
    "updatedAt": null,
    "roles": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "name": "string",
        "slug": "string"
      }
    ],
    "activeSessionCount": 1
  }
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
PUT/customer_accounts/admin/users/{id}

Update customer user (admin)

Updates a customer user. Staff can update status, lock, CRM links, and roles. Role assignment bypasses customer_assignable check.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "lockedUntil": null,
  "personEntityId": null,
  "customerEntityId": null
}

Responses

200User updated
Content-Type: application/json
{
  "ok": true
}
400Validation failed or role not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"lockedUntil\": null,
  \"personEntityId\": null,
  \"customerEntityId\": null
}"
DELETE/customer_accounts/admin/users/{id}

Delete customer user (admin)

Soft deletes a customer user and revokes all their active sessions.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200User deleted
Content-Type: application/json
{
  "ok": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
POST/customer_accounts/admin/users/{id}/reset-password

Reset customer user password (admin)

Allows staff to set a new password for a customer user.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "newPassword": "string"
}

Responses

200Password reset
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000/reset-password" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"newPassword\": \"string\"
}"
POST/customer_accounts/admin/users/{id}/send-reset-link

Send password reset link for customer user (admin)

Creates a password reset token for a customer user and returns a reset link URL. The admin must prepend the appropriate portal domain/slug to the relative URL.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Reset link generated
Content-Type: application/json
{
  "ok": true,
  "resetLink": "string"
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000/send-reset-link" \
  -H "Accept: application/json"
POST/customer_accounts/admin/users/{id}/verify-email

Verify customer user email (admin)

Allows staff to manually mark a customer user email as verified.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Email verified
Content-Type: application/json
{
  "ok": true
}
401Not authenticated
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403Insufficient permissions
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404User not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000/verify-email" \
  -H "Accept: application/json"

Customer Authentication

Showing 8 of 8 endpoints
POST/customer_accounts/email/verify

Verify customer email address

Validates the email verification token and marks the email as verified.

Request body (application/json)

{
  "token": "string"
}

Responses

200Email verified
Content-Type: application/json
{
  "ok": true
}
400Invalid or expired token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/email/verify" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"token\": \"string\"
}"
POST/customer_accounts/invitations/accept

Accept customer invitation

Accepts an invitation, creates the user account, assigns roles, and auto-logs in.

Request body (application/json)

{
  "token": "string",
  "password": "string",
  "displayName": "string"
}

Responses

201Invitation accepted and user created
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
400Invalid or expired invitation
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/invitations/accept" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"token\": \"string\",
  \"password\": \"string\",
  \"displayName\": \"string\"
}"
POST/customer_accounts/login

Authenticate customer credentials

Validates customer credentials and issues JWT + session cookies.

Request body (application/json)

{
  "email": "user@example.com",
  "password": "string"
}

Responses

200Login successful
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
400Validation failed
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid credentials
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many login attempts
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\"
}"
POST/customer_accounts/magic-link/request

Request magic link login

Sends a magic link to the customer email. Always returns 200 to prevent enumeration.

Request body (application/json)

{
  "email": "user@example.com"
}

Responses

200Request accepted
Content-Type: application/json
{
  "ok": true
}
429Too many requests
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/magic-link/request" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\"
}"
POST/customer_accounts/magic-link/verify

Verify magic link token

Validates the magic link token, auto-verifies email, and creates a session.

Request body (application/json)

{
  "token": "string"
}

Responses

200Login successful
Content-Type: application/json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
400Invalid or expired token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Account not found
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/magic-link/verify" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"token\": \"string\"
}"
POST/customer_accounts/password/reset-confirm

Confirm customer password reset

Validates the reset token and sets a new password. Revokes all existing sessions.

Request body (application/json)

{
  "token": "string",
  "password": "string"
}

Responses

200Password reset successful
Content-Type: application/json
{
  "ok": true
}
400Invalid or expired token
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/password/reset-confirm" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"token\": \"string\",
  \"password\": \"string\"
}"
POST/customer_accounts/password/reset-request

Request customer password reset

Initiates a password reset flow. Always returns 200 to prevent email enumeration.

Request body (application/json)

{
  "email": "user@example.com"
}

Responses

200Request accepted
Content-Type: application/json
{
  "ok": true
}
429Too many requests
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/password/reset-request" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\"
}"
POST/customer_accounts/signup

Register a new customer account

Accepts a signup request and always returns 202 to prevent account enumeration.

Request body (application/json)

{
  "email": "user@example.com",
  "password": "string",
  "displayName": "string"
}

Responses

202Signup accepted
Content-Type: application/json
{
  "ok": true
}
400Validation failed or invalid request origin
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many signup attempts
Content-Type: application/json
{
  "error": "string"
}
500Signup email origin is not configured
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customer_accounts/signup" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\",
  \"displayName\": \"string\"
}"

Customers

Showing 20 of 101 endpoints
GET/customers/activities
Auth requiredcustomers.activities.view

List activitys

Returns a paginated collection of activitys scoped to the authenticated organization. Requires features: customers.activities.view

Parameters

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

Responses

200Paginated activitys
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "activityType": "string",
      "subject": null,
      "body": null,
      "occurredAt": null,
      "createdAt": "string",
      "appearanceIcon": null,
      "appearanceColor": null,
      "entityId": null,
      "authorUserId": null,
      "authorName": null,
      "authorEmail": null,
      "dealId": null,
      "dealTitle": null,
      "customValues": null,
      "activityTypeLabel": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/activities?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customers/activities
Auth requiredcustomers.activities.manage

Create activity

DEPRECATED (sunset 2026-06-30): Creates a timeline activity. Use POST /api/customers/interactions instead. Requires features: customers.activities.manage

Request body (application/json)

{
  "entityId": "00000000-0000-4000-8000-000000000000",
  "activityType": "string",
  "phoneNumber": null,
  "appearanceIcon": null,
  "appearanceColor": null
}

Responses

201Activity created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/activities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"00000000-0000-4000-8000-000000000000\",
  \"activityType\": \"string\",
  \"phoneNumber\": null,
  \"appearanceIcon\": null,
  \"appearanceColor\": null
}"
PUT/customers/activities
Auth requiredcustomers.activities.manage

Update activity

DEPRECATED (sunset 2026-06-30): Updates an activity. Use PUT /api/customers/interactions instead. Requires features: customers.activities.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "phoneNumber": null,
  "appearanceIcon": null,
  "appearanceColor": null
}

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customers/activities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"phoneNumber\": null,
  \"appearanceIcon\": null,
  \"appearanceColor\": null
}"
DELETE/customers/activities
Auth requiredcustomers.activities.manage

Delete activity

DEPRECATED (sunset 2026-06-30): Deletes an activity. Use DELETE /api/customers/interactions instead. Requires features: customers.activities.manage

Request body (application/json)

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

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customers/activities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/customers/addresses
Auth requiredcustomers.activities.view

List addresss

Returns a paginated collection of addresss scoped to the authenticated organization. Requires features: customers.activities.view

Parameters

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

Responses

200Paginated addresss
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entity_id": "00000000-0000-4000-8000-000000000000",
      "name": null,
      "purpose": null,
      "company_name": null,
      "address_line1": null,
      "address_line2": null,
      "building_number": null,
      "flat_number": null,
      "city": null,
      "region": null,
      "postal_code": null,
      "country": null,
      "latitude": null,
      "longitude": null,
      "is_primary": null,
      "organization_id": null,
      "tenant_id": null,
      "updated_at": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/addresses?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customers/addresses
Auth requiredcustomers.activities.manage

Create address

Creates a customer address record and associates it with the referenced entity. Requires features: customers.activities.manage

Request body (application/json)

{
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "entityId": "00000000-0000-4000-8000-000000000000",
  "addressLine1": "string",
  "latitude": null,
  "longitude": null
}

Responses

201Address created
Content-Type: application/json
{
  "id": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/addresses" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"organizationId\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",
  \"entityId\": \"00000000-0000-4000-8000-000000000000\",
  \"addressLine1\": \"string\",
  \"latitude\": null,
  \"longitude\": null
}"
PUT/customers/addresses
Auth requiredcustomers.activities.manage

Update address

Updates fields on an existing customer address. Requires features: customers.activities.manage

Request body (application/json)

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

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customers/addresses" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"latitude\": null,
  \"longitude\": null
}"
DELETE/customers/addresses
Auth requiredcustomers.activities.manage

Delete address

Deletes an address by id. The identifier may be included in the body or query. Requires features: customers.activities.manage

Request body (application/json)

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

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customers/addresses" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/customers/assignable-staff
Auth requiredcustomers.roles.view

DEPRECATED: use GET /api/staff/team-members/assignable instead.

Deprecated. Returns 308 Permanent Redirect to /api/staff/team-members/assignable preserving the query string. Will be removed no earlier than the next major release. Requires features: customers.roles.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—

Responses

200Assignable staff members (only reachable by following the redirect).
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "teamMemberId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "displayName": "string",
      "email": null,
      "teamName": null,
      "user": null,
      "team": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
308Permanent redirect to /api/staff/team-members/assignable.
Content-Type: application/json
{
  "error": "string"
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/assignable-staff?page=1&pageSize=24" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/customers/comments
Auth requiredcustomers.activities.view

List comments

Returns a paginated collection of comments scoped to the authenticated organization. Requires features: customers.activities.view

Parameters

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

Responses

200Paginated comments
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entity_id": null,
      "deal_id": null,
      "body": null,
      "author_user_id": null,
      "appearance_icon": null,
      "appearance_color": null,
      "organization_id": null,
      "tenant_id": null,
      "created_at": null,
      "updated_at": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/comments?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customers/comments
Auth requiredcustomers.activities.manage

Create comment

Adds a comment to a customer timeline. Requires features: customers.activities.manage

Request body (application/json)

{
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "entityId": "00000000-0000-4000-8000-000000000000",
  "body": "string",
  "appearanceIcon": null,
  "appearanceColor": null
}

Responses

201Comment created
Content-Type: application/json
{
  "id": null,
  "authorUserId": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/comments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"organizationId\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",
  \"entityId\": \"00000000-0000-4000-8000-000000000000\",
  \"body\": \"string\",
  \"appearanceIcon\": null,
  \"appearanceColor\": null
}"
PUT/customers/comments
Auth requiredcustomers.activities.manage

Update comment

Updates an existing timeline comment. Requires features: customers.activities.manage

Request body (application/json)

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

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customers/comments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"appearanceIcon\": null,
  \"appearanceColor\": null
}"
DELETE/customers/comments
Auth requiredcustomers.activities.manage

Delete comment

Deletes a comment identified by `id` supplied via body or query string. Requires features: customers.activities.manage

Request body (application/json)

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

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customers/comments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/customers/companies
Auth requiredcustomers.companies.view

List companies

Returns a paginated collection of companies scoped to the authenticated organization. Requires features: customers.companies.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
emailqueryNoany—
emailStartsWithqueryNoany—
emailContainsqueryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
statusqueryNoany—
lifecycleStagequeryNoany—
sourcequeryNoany—
hasEmailqueryNoany—
hasPhonequeryNoany—
hasNextInteractionqueryNoany—
createdFromqueryNoany—
createdToqueryNoany—
idqueryNoany—
tagIdsqueryNoany—
tagIdsEmptyqueryNoany—
excludeIdsqueryNoany—
excludeLinkedPersonIdqueryNoany—
excludeLinkedCompanyIdqueryNoany—
excludeLinkedDealIdqueryNoany—
idsqueryNoanyComma-separated list of record UUIDs to filter by (max 200).

Responses

200Paginated companies
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "description": null,
      "owner_user_id": null,
      "primary_email": null,
      "primary_phone": null,
      "status": null,
      "lifecycle_stage": null,
      "source": null,
      "next_interaction_at": null,
      "next_interaction_name": null,
      "next_interaction_ref_id": null,
      "next_interaction_icon": null,
      "next_interaction_color": null,
      "organization_id": null,
      "tenant_id": null,
      "created_at": null
    }
  ],
  "total": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/companies?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/customers/companies
Auth requiredcustomers.companies.manage

Create company

Creates a company record and associated profile data. Requires features: customers.companies.manage

Request body (application/json)

{
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "displayName": "string",
  "description": null,
  "primaryEmail": null,
  "primaryPhone": null,
  "nextInteraction": null,
  "legalName": null,
  "brandName": null,
  "domain": null,
  "websiteUrl": null,
  "sizeBucket": null,
  "annualRevenue": null
}

Responses

201Company created
Content-Type: application/json
{
  "id": null,
  "companyId": null
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/customers/companies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"organizationId\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",
  \"displayName\": \"string\",
  \"description\": null,
  \"primaryEmail\": null,
  \"primaryPhone\": null,
  \"nextInteraction\": null,
  \"legalName\": null,
  \"brandName\": null,
  \"domain\": null,
  \"websiteUrl\": null,
  \"sizeBucket\": null,
  \"annualRevenue\": null
}"
PUT/customers/companies
Auth requiredcustomers.companies.manage

Update company

Updates company profile fields, tags, or custom attributes. Requires features: customers.companies.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "description": null,
  "primaryEmail": null,
  "primaryPhone": null,
  "nextInteraction": null,
  "legalName": null,
  "brandName": null,
  "domain": null,
  "websiteUrl": null,
  "sizeBucket": null,
  "annualRevenue": null
}

Responses

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

Example

curl -X PUT "https://portal.gt.freighttech.org/api/customers/companies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"description\": null,
  \"primaryEmail\": null,
  \"primaryPhone\": null,
  \"nextInteraction\": null,
  \"legalName\": null,
  \"brandName\": null,
  \"domain\": null,
  \"websiteUrl\": null,
  \"sizeBucket\": null,
  \"annualRevenue\": null
}"
DELETE/customers/companies
Auth requiredcustomers.companies.manage

Delete company

Deletes a company by id. The identifier can be provided via body or query. Requires features: customers.companies.manage

Request body (application/json)

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

Responses

200Company deleted
Content-Type: application/json
{
  "ok": true
}
422Company has dependent records (people, deals, or direct staff); unlink or reassign before delete.
Content-Type: application/json
{
  "error": "string",
  "code": "COMPANY_HAS_DEPENDENTS"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/customers/companies" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
GET/customers/companies/{id}
Auth requiredcustomers.companies.view

Fetch company with related data

Returns a company customer record with optional related resources such as addresses, comments, activities, interactions, deals, todos, and linked people. Requires features: customers.companies.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—
includequeryNoanyComma-separated list of relations to include (addresses, comments, activities, interactions, deals, todos, people).

Responses

200Company detail payload
Content-Type: application/json
{
  "interactionMode": "canonical",
  "company": {
    "id": "00000000-0000-4000-8000-000000000000",
    "displayName": null,
    "description": null,
    "ownerUserId": null,
    "primaryEmail": null,
    "primaryPhone": null,
    "status": null,
    "lifecycleStage": null,
    "source": null,
    "nextInteractionAt": null,
    "nextInteractionName": null,
    "nextInteractionRefId": null,
    "nextInteractionIcon": null,
    "nextInteractionColor": null,
    "organizationId": null,
    "tenantId": null,
    "temperature": null,
    "renewalQuarter": null,
    "createdAt": "string",
    "updatedAt": "string"
  },
  "profile": null,
  "customFields": {},
  "tags": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "label": "string",
      "color": null
    }
  ],
  "addresses": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": null,
      "purpose": null,
      "addressLine1": null,
      "addressLine2": null,
      "buildingNumber": null,
      "flatNumber": null,
      "city": null,
      "region": null,
      "postalCode": null,
      "country": null,
      "latitude": null,
      "longitude": null,
      "isPrimary": null,
      "createdAt": "string"
    }
  ],
  "comments": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "body": null,
      "authorUserId": null,
      "authorName": null,
      "authorEmail": null,
      "dealId": null,
      "createdAt": "string",
      "appearanceIcon": null,
      "appearanceColor": null
    }
  ],
  "activities": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "activityType": "string",
      "subject": null,
      "body": null,
      "occurredAt": null,
      "dealId": null,
      "authorUserId": null,
      "authorName": null,
      "authorEmail": null,
      "createdAt": "string",
      "appearanceIcon": null,
      "appearanceColor": null
    }
  ],
  "interactions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entityId": null,
      "interactionType": "string",
      "title": null,
      "body": null,
      "status": "string",
      "scheduledAt": null,
      "occurredAt": null,
      "priority": null,
      "authorUserId": null,
      "ownerUserId": null,
      "dealId": null,
      "organizationId": null,
      "tenantId": null,
      "authorName": null,
      "authorEmail": null,
      "dealTitle": null,
      "customValues": null,
      "appearanceIcon": null,
      "appearanceColor": null,
      "source": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "deals": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "title": null,
      "status": null,
      "pipelineStage": null,
      "valueAmount": null,
      "valueCurrency": null,
      "probability": null,
      "expectedCloseAt": null,
      "ownerUserId": null,
      "source": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "todos": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "todoId": "00000000-0000-4000-8000-000000000000",
      "todoSource": "string",
      "createdAt": "string",
      "createdByUserId": null,
      "title": null,
      "isDone": null,
      "priority": null,
      "severity": null,
      "description": null,
      "dueAt": null,
      "todoOrganizationId": null,
      "customValues": null
    }
  ],
  "people": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "displayName": null,
      "primaryEmail": null,
      "primaryPhone": null,
      "status": null,
      "lifecycleStage": null,
      "jobTitle": null,
      "department": null,
      "createdAt": "string",
      "organizationId": null,
      "source": null,
      "temperature": null,
      "linkedAt": null
    }
  ],
  "viewer": {
    "userId": null,
    "name": null,
    "email": null
  }
}
400Invalid identifier
Content-Type: application/json
{
  "error": "string"
}
404Company not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/companies/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/customers/companies/{id}/people
Auth requiredcustomers.companies.view

List linked people for a company

Requires features: customers.companies.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—
pagequeryNoany—
pageSizequeryNoany—
searchqueryNoany—
sortqueryNoany—

Responses

200Paginated linked people
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "displayName": "string",
      "primaryEmail": null,
      "primaryPhone": null,
      "status": null,
      "lifecycleStage": null,
      "jobTitle": null,
      "department": null,
      "createdAt": "string",
      "organizationId": null,
      "temperature": null,
      "source": null,
      "linkedAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/companies/:id/people?page=1&pageSize=20&sort=name-asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/customers/companies/{id}/roles
Auth requiredcustomers.roles.view

List roles for a company

Requires features: customers.roles.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Role assignments
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entityType": "company",
      "entityId": "00000000-0000-4000-8000-000000000000",
      "userId": "00000000-0000-4000-8000-000000000000",
      "userName": null,
      "userEmail": null,
      "userPhone": null,
      "roleType": "string",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ]
}
400Invalid request
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/customers/companies/00000000-0000-4000-8000-000000000000/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Dashboards

Showing 10 of 10 endpoints
GET/dashboards/layout
Auth requireddashboards.view

Load the current dashboard layout

Returns the saved widget layout together with the widgets the current user is allowed to place. Requires features: dashboards.view

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
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/layout
Auth requireddashboards.configure

Persist dashboard layout changes

Saves the provided widget ordering, sizes, and settings for the current user. Requires features: dashboards.configure

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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requireddashboards.configure

Update a dashboard layout item

Adjusts the size or settings for a single widget within the dashboard layout. Requires features: dashboards.configure

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"
}
404Item not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://portal.gt.freighttech.org/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 requireddashboards.admin.assign-widgets

Fetch widget assignments for a role

Returns the widgets explicitly assigned to the given role together with the evaluation scope. Requires features: dashboards.admin.assign-widgets

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dashboards/roles/widgets?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/roles/widgets
Auth requireddashboards.admin.assign-widgets

Update widgets assigned to a role

Persists the widget list for a role within the provided tenant and organization scope. Requires features: dashboards.admin.assign-widgets

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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requireddashboards.admin.assign-widgets

Read widget overrides for a user

Returns the widgets inherited and explicitly configured for the requested user within the current scope. Requires features: dashboards.admin.assign-widgets

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dashboards/users/widgets?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/dashboards/users/widgets
Auth requireddashboards.admin.assign-widgets

Update user-specific dashboard widgets

Sets the widget override mode and allowed widgets for a user. Passing `mode: inherit` clears overrides. Requires features: dashboards.admin.assign-widgets

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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requireddashboards.admin.assign-widgets

List available dashboard widgets

Returns the catalog of widgets that modules expose, including defaults and feature requirements. Requires features: dashboards.admin.assign-widgets

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
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dashboards/widgets/catalog" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dashboards/widgets/data
Auth requiredanalytics.view

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. Requires features: analytics.view

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
  }
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredanalytics.view

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. Requires features: analytics.view

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
        }
      }
    }
  ]
}
400Invalid request payload
Content-Type: application/json
{
  "error": "string"
}
500Internal server error
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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\"
        }
      }
    }
  ]
}"

Dictionaries

Showing 11 of 11 endpoints
GET/dictionaries
Auth requireddictionaries.view

List dictionaries

Returns dictionaries accessible to the current organization, optionally including inactive records. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
includeInactivequeryNoany—

Responses

200Dictionary collection.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "key": "string",
      "name": "string",
      "description": null,
      "isSystem": true,
      "isActive": true,
      "managerVisibility": null,
      "organizationId": null,
      "createdAt": "string",
      "updatedAt": null
    }
  ]
}
500Failed to load dictionaries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries
Auth requireddictionaries.manage

Create dictionary

Registers a dictionary scoped to the current organization. Requires features: dictionaries.manage

Request body (application/json)

{
  "key": "string",
  "name": "string"
}

Responses

201Dictionary created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
409Dictionary key already exists
Content-Type: application/json
{
  "error": "string"
}
500Failed to create dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"key\": \"string\",
  \"name\": \"string\"
}"
GET/dictionaries/{dictionaryId}
Auth requireddictionaries.view

Get dictionary

Returns details for the specified dictionary, including inheritance flags. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Responses

200Dictionary details.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PATCH/dictionaries/{dictionaryId}
Auth requireddictionaries.manage

Update dictionary

Updates mutable attributes of the dictionary. Currency dictionaries are protected from modification. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Request body (application/json)

{}

Responses

200Dictionary updated.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "key": "string",
  "name": "string",
  "description": null,
  "isSystem": true,
  "isActive": true,
  "managerVisibility": null,
  "organizationId": null,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed or protected dictionary
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
409Dictionary key already exists
Content-Type: application/json
{
  "error": "string"
}
500Failed to update dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
DELETE/dictionaries/{dictionaryId}
Auth requireddictionaries.manage

Delete dictionary

Soft deletes the dictionary unless it is the protected currency dictionary. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Responses

200Dictionary archived.
Content-Type: application/json
{
  "ok": true
}
400Protected dictionary cannot be deleted
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to delete dictionary
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/dictionaries/{dictionaryId}/entries
Auth requireddictionaries.view

List dictionary entries

Returns entries for the specified dictionary ordered by its configured entry sort mode. Requires features: dictionaries.view

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Responses

200Dictionary entries.
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "value": "string",
      "label": "string",
      "color": null,
      "icon": null,
      "position": 1,
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null
    }
  ]
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to load dictionary entries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries/{dictionaryId}/entries
Auth requireddictionaries.manage

Create dictionary entry

Creates a new entry in the specified dictionary. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Request body (application/json)

{
  "value": "string",
  "color": null,
  "icon": null
}

Responses

201Dictionary entry created.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "position": 1,
  "isDefault": true,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to create dictionary entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"value\": \"string\",
  \"color\": null,
  \"icon\": null
}"
PATCH/dictionaries/{dictionaryId}/entries/{entryId}
Auth requireddictionaries.manage

Update dictionary entry

Updates the specified dictionary entry using the command bus pipeline. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—
entryIdpathYesany—

Request body (application/json)

{
  "color": null,
  "icon": null
}

Responses

200Dictionary entry updated.
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "position": 1,
  "isDefault": true,
  "createdAt": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to update entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PATCH "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"color\": null,
  \"icon\": null
}"
DELETE/dictionaries/{dictionaryId}/entries/{entryId}
Auth requireddictionaries.manage

Delete dictionary entry

Deletes the specified dictionary entry via the command bus. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—
entryIdpathYesany—

Responses

200Entry deleted.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to delete entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/dictionaries/{dictionaryId}/entries/reorder
Auth requireddictionaries.manage

Reorder dictionary entries

Updates the position of dictionary entries for drag-and-drop reordering. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Request body (application/json)

{
  "entries": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "position": 1
    }
  ]
}

Responses

200Entries reordered.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to reorder entries
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/reorder" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entries\": [
    {
      \"id\": \"00000000-0000-4000-8000-000000000000\",
      \"position\": 1
    }
  ]
}"
POST/dictionaries/{dictionaryId}/entries/set-default
Auth requireddictionaries.manage

Set default dictionary entry

Marks the specified entry as the default for this dictionary, clearing any previous default. Requires features: dictionaries.manage

Parameters

NameInRequiredSchemaDescription
dictionaryIdpathYesany—

Request body (application/json)

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

Responses

200Default entry set.
Content-Type: application/json
{
  "ok": true
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
404Dictionary or entry not found
Content-Type: application/json
{
  "error": "string"
}
500Failed to set default entry
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/dictionaries/00000000-0000-4000-8000-000000000000/entries/set-default" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entryId\": \"00000000-0000-4000-8000-000000000000\"
}"

Directory

Showing 11 of 11 endpoints
GET/directory/organization-branding
Auth requireddirectory.organizations.view

Read sidebar branding for the selected organization

Returns the logo URL used by the backend sidebar for the currently selected organization. Requires features: directory.organizations.view

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/directory/organization-branding" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/directory/organization-branding
Auth requireddirectory.organizations.manage

Update sidebar branding for the selected organization

Stores an external image URL or an internal attachment image URL as the selected organization logo. Requires features: directory.organizations.manage

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,
  "updatedAt": null
}
400Save failed
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://portal.gt.freighttech.org/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
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/directory/organization-switcher" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/directory/organizations
Auth requireddirectory.organizations.view

List organizations

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

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/directory/organizations?page=1&pageSize=50&view=options" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/organizations
Auth requireddirectory.organizations.manage

Create organization

Creates a new organization within a tenant and optionally assigns hierarchy relationships. Requires features: directory.organizations.manage

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requireddirectory.organizations.manage

Update organization

Updates organization details and hierarchy assignments. Requires features: directory.organizations.manage

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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requireddirectory.organizations.manage

Delete organization

Soft deletes an organization identified by id. Requires features: directory.organizations.manage

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"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/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 requireddirectory.tenants.view

List tenants

Returns tenants visible to the current user with optional search and pagination. Requires features: directory.tenants.view

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/directory/tenants?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/directory/tenants
Auth requireddirectory.tenants.manage

Create tenant

Creates a new tenant and returns its identifier. Requires features: directory.tenants.manage

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
PUT/directory/tenants
Auth requireddirectory.tenants.manage

Update tenant

Updates tenant properties such as name or activation state. Requires features: directory.tenants.manage

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"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requireddirectory.tenants.manage

Delete tenant

Soft deletes the tenant identified by id. Requires features: directory.tenants.manage

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"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/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 18 of 18 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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions
Auth requiredentities.definitions.manage

Upsert custom field definition

Creates or updates a custom field definition for the current tenant/org scope. Requires features: entities.definitions.manage

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredentities.definitions.manage

Soft delete custom field definition

Marks the specified definition inactive and tombstones it for the current scope. Requires features: entities.definitions.manage

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"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/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 requiredentities.definitions.manage

Save multiple custom field definitions

Creates or updates multiple definitions for a single entity in one transaction. Requires features: entities.definitions.manage

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"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredentities.definitions.manage

Get management snapshot

Returns scoped custom field definitions (including inactive tombstones) for administration interfaces. Requires features: entities.definitions.manage

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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/definitions.manage?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/definitions.restore
Auth requiredentities.definitions.manage

Restore definition

Reactivates a previously soft-deleted definition within the current tenant/org scope. Requires features: entities.definitions.manage

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"
}
404Definition not found
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredentities.definitions.manage

Fetch encryption map

Returns the encrypted field map for the current tenant/organization scope. Requires features: entities.definitions.manage

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/encryption?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/encryption
Auth requiredentities.definitions.manage

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. Requires features: entities.definitions.manage

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/entities
Auth requiredentities.definitions.manage

Upsert custom entity

Creates or updates a tenant/org scoped custom entity definition. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string",
  "label": "string",
  "description": null,
  "showInSidebar": 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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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
}"
DELETE/entities/entities
Auth requiredentities.definitions.manage

Soft delete custom entity

Marks the specified custom entity inactive within the current scope. Requires features: entities.definitions.manage

Request body (application/json)

{
  "entityId": "string"
}

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\"
}"
GET/entities/filter-suggestions
Auth required

Get filter suggestions for a field

Returns distinct values for a specific field from any entity. Used by DynamicTable filter popover to provide autocomplete suggestions for large datasets.

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—
fieldqueryYesany—
queryqueryNoany—
limitqueryNoany—

Responses

200List of unique values for the field
Content-Type: application/json
{
  "items": [
    "string"
  ]
}
400Invalid parameters
Content-Type: application/json
{
  "error": "string",
  "items": [
    "string"
  ]
}
500Server error
Content-Type: application/json
{
  "error": "string",
  "items": [
    "string"
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/filter-suggestions?entityId=string&field=string&query=&limit=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/entities/records
Auth requiredentities.records.view

List records

Returns paginated records for the supplied entity. Supports custom field filters, exports, and soft-delete toggles. Requires features: entities.records.view

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"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/records?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/entities/records
Auth requiredentities.records.manage

Create record

Creates a record for the given entity. When `recordId` is omitted or not a UUID the data engine will generate one automatically. Requires features: entities.records.manage

Request body (application/json)

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

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"values\": {}
}"
PUT/entities/records
Auth requiredentities.records.manage

Update record

Updates an existing record. If the provided recordId is not a UUID the record will be created instead to support optimistic flows. Requires features: entities.records.manage

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"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/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 requiredentities.records.manage

Delete record

Soft deletes the specified record within the current tenant/org scope. Requires features: entities.records.manage

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"
}
404Record not found
Content-Type: application/json
{
  "error": "string"
}
500Unexpected failure
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/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 requiredentities.definitions.view

List relation options

Returns up to 200 option entries for populating relation dropdowns, automatically resolving label fields when omitted. Requires features: entities.definitions.view

Parameters

NameInRequiredSchemaDescription
entityIdqueryYesany—
labelFieldqueryNoany—
qqueryNoany—
idsqueryNoany—
routeContextFieldsqueryNoany—

Responses

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

Example

curl -X GET "https://portal.gt.freighttech.org/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"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/entities/sidebar-entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

GT Accounts

Showing 18 of 18 endpoints
GET/gt_accounts/feature-catalog
Auth requiredgt_accounts.view

GT customer-portal feature catalogue

Requires features: gt_accounts.view

Responses

200Catalogue
Content-Type: application/json
{
  "areas": [
    "string"
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/feature-catalog" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_accounts/mobile/login

Customer sign-in for native (mobile) clients — tokens in the body

Request body (application/json)

{
  "email": "user@example.com",
  "password": "string"
}

Responses

200Signed in
Content-Type: application/json
{
  "ok": true,
  "token": "string",
  "refreshToken": "string",
  "expiresIn": 1,
  "user": null,
  "resolvedFeatures": [
    "string"
  ]
}
400Invalid body or tenant
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Invalid email or password
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Unknown organization slug
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
429Too many attempts
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/mobile/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\"
}"
POST/gt_accounts/mobile/logout

Sign out a native (mobile) client: revoke its session

Request body (application/json)

{
  "refreshToken": "string"
}

Responses

200Session revoked (or already gone)
Content-Type: application/json
{
  "ok": true
}
400Invalid body
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/mobile/logout" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"refreshToken\": \"string\"
}"
POST/gt_accounts/mobile/refresh

Refresh the customer access token for native (mobile) clients

Request body (application/json)

{
  "refreshToken": "string"
}

Responses

200New access token
Content-Type: application/json
{
  "ok": true,
  "accessToken": "string",
  "expiresIn": 1,
  "resolvedFeatures": [
    "string"
  ]
}
400Invalid body
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
401Session revoked, expired or account inactive — sign in again
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/mobile/refresh" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"refreshToken\": \"string\"
}"
POST/gt_accounts/password-reset

Request a customer password reset link (always 200; e-mailed when delivery is configured)

Request body (application/json)

{
  "email": "user@example.com",
  "orgSlug": "string"
}

Responses

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

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/password-reset" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"orgSlug\": \"string\"
}"
GET/gt_accounts/portal/assignable-roles

Customer roles a portal admin can assign

Responses

200Roles
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "name": "string",
      "slug": "string"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/portal/assignable-roles" \
  -H "Accept: application/json"
GET/gt_accounts/portal/invitations

Pending invitations of the caller's company (portal.users.invite or .manage)

Responses

200Invitations
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "string",
      "email": "string",
      "displayName": null,
      "roles": [
        {
          "id": "string",
          "name": "string"
        }
      ],
      "createdAt": "string",
      "expiresAt": "string"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/portal/invitations" \
  -H "Accept: application/json"
POST/gt_accounts/portal/invitations

Invite a colleague: one-time acceptance link (e-mailed when configured, always returned to the inviter)

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invited
Content-Type: application/json
{
  "ok": true,
  "invitation": {
    "id": "string",
    "email": "string",
    "displayName": null,
    "roles": [
      {
        "id": "string",
        "name": "string"
      }
    ],
    "createdAt": "string",
    "expiresAt": "string"
  },
  "inviteUrl": "string",
  "emailDelivery": "sent"
}
403No invite permission or role not assignable
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409E-mail already has a portal account
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/portal/invitations" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
DELETE/gt_accounts/portal/invitations/{id}

Cancel a pending invitation of the caller's company

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Cancelled
Content-Type: application/json
{
  "ok": true
}
404No such pending invitation in this company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/gt_accounts/portal/invitations/:id" \
  -H "Accept: application/json"
GET/gt_accounts/portal/landing

Landing page of the signed-in portal user (customer or partner shell)

Responses

200Landing
Content-Type: application/json
{
  "ok": true,
  "partyKind": "customer",
  "home": "string"
}
401Not signed in
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
403No linked portal company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/portal/landing" \
  -H "Accept: application/json"
GET/gt_accounts/portal/me

Current portal customer context

Responses

200Context
Content-Type: application/json
{
  "ok": true,
  "areas": [
    "string"
  ],
  "features": [
    "string"
  ],
  "roles": [
    {
      "slug": "string",
      "name": "string"
    }
  ]
}
403No linked portal company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/portal/me" \
  -H "Accept: application/json"
GET/gt_accounts/profiles
Auth requiredgt_accounts.view

List portal customers

Requires features: gt_accounts.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
companyIdqueryNoany—
partyKindqueryNoany—
searchqueryNoany—

Responses

200Profiles
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "companyId": "string",
      "displayName": "string",
      "partyKind": "customer",
      "taxId": null,
      "enabledAreas": [
        "string"
      ]
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/profiles?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_accounts/profiles
Auth requiredgt_accounts.manage

Create a portal customer profile for a CRM company

Requires features: gt_accounts.manage

Request body (application/json)

{
  "companyId": "00000000-0000-4000-8000-000000000000",
  "displayName": "string",
  "taxId": null,
  "eori": null,
  "serviceCompanies": [],
  "enabledAreas": [
    "dashboard",
    "shipments",
    "customs",
    "documents",
    "invoices",
    "deliveries",
    "offers",
    "reports",
    "news",
    "help"
  ],
  "preferredIdentifier": "gt_ref",
  "paymentTermDays": null,
  "deliveryRules": {},
  "accountManagers": [],
  "peerParties": [],
  "isActive": true,
  "partyKind": "customer"
}

Responses

201Created
Content-Type: application/json
{
  "id": "string",
  "companyId": "string",
  "displayName": "string",
  "partyKind": "customer",
  "taxId": null,
  "enabledAreas": [
    "string"
  ]
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/profiles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"companyId\": \"00000000-0000-4000-8000-000000000000\",
  \"displayName\": \"string\",
  \"taxId\": null,
  \"eori\": null,
  \"serviceCompanies\": [],
  \"enabledAreas\": [
    \"dashboard\",
    \"shipments\",
    \"customs\",
    \"documents\",
    \"invoices\",
    \"deliveries\",
    \"offers\",
    \"reports\",
    \"news\",
    \"help\"
  ],
  \"preferredIdentifier\": \"gt_ref\",
  \"paymentTermDays\": null,
  \"deliveryRules\": {},
  \"accountManagers\": [],
  \"peerParties\": [],
  \"isActive\": true,
  \"partyKind\": \"customer\"
}"
PUT/gt_accounts/profiles
Auth requiredgt_accounts.manage

Update a portal customer profile

Requires features: gt_accounts.manage

Request body (application/json)

{
  "taxId": null,
  "eori": null,
  "paymentTermDays": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Updated
Content-Type: application/json
{
  "id": "string",
  "companyId": "string",
  "displayName": "string",
  "partyKind": "customer",
  "taxId": null,
  "enabledAreas": [
    "string"
  ]
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_accounts/profiles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"taxId\": null,
  \"eori\": null,
  \"paymentTermDays\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/gt_accounts/profiles
Auth requiredgt_accounts.manage

Deactivate (soft-delete) a portal customer profile

Requires features: gt_accounts.manage

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/gt_accounts/profiles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_accounts/profiles/{id}
Auth requiredgt_accounts.view

Portal customer profile detail

Requires features: gt_accounts.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Profile
Content-Type: application/json
{
  "id": "string",
  "userCount": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/profiles/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_accounts/profiles/{id}/invitations
Auth requiredgt_accounts.view

Pending invitations of a portal company and the roles of its audience

Requires features: gt_accounts.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Invitations
Content-Type: application/json
{
  "ok": true,
  "partyKind": "string",
  "items": [
    {
      "id": "string",
      "email": "string",
      "displayName": null,
      "roles": [
        {
          "id": "string",
          "name": "string"
        }
      ],
      "createdAt": "string",
      "expiresAt": "string"
    }
  ],
  "roles": [
    {
      "id": "string",
      "slug": "string",
      "name": "string"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_accounts/profiles/:id/invitations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_accounts/profiles/{id}/invitations
Auth requiredgt_accounts.manage

Staff invites a user into a portal company (customer or partner) with roles of its audience

Requires features: gt_accounts.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invited
Content-Type: application/json
{
  "ok": true,
  "invitation": {
    "id": "string",
    "email": "string",
    "displayName": null,
    "roles": [
      {
        "id": "string",
        "name": "string"
      }
    ],
    "createdAt": "string",
    "expiresAt": "string"
  },
  "inviteUrl": "string",
  "emailDelivery": "sent"
}
409E-mail already has a portal account
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_accounts/profiles/:id/invitations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"

GT Customs

Showing 4 of 4 endpoints
GET/gt_customs/cases
Auth requiredgt_customs.view

List projected customs cases (staff, includes unmatched rows and amounts)

Requires features: gt_customs.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
searchqueryNoany—
stepCodequeryNoany—
customerCompanyIdqueryNoany—
matchedqueryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—

Responses

200Customs cases
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "caseReference": null,
      "stepCode": "string",
      "customerCompanyId": null
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_customs/cases?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_customs/portal/by-shipment/{shipmentId}

Customs cases linked to a shipment (customer)

Parameters

NameInRequiredSchemaDescription
shipmentIdpathYesany—

Responses

200Cases (empty when none or when the shipment is not the company's)
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "caseReference": null,
      "mrn": null,
      "blNumber": null,
      "containerNumbers": [
        "string"
      ],
      "shipmentId": null,
      "shipmentReference": null,
      "stepCode": "string",
      "steps": [
        {
          "code": "string"
        }
      ],
      "inspection": true,
      "missingDocuments": [
        {
          "kind": null,
          "label": "string",
          "blocking": true
        }
      ],
      "cleared": true,
      "releasedAt": null,
      "eta": null,
      "dutyStatus": "paid",
      "vatStatus": "paid",
      "documentCount": 1,
      "updatedAt": "string"
    }
  ]
}
403No customs access
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_customs/portal/by-shipment/:shipmentId" \
  -H "Accept: application/json"
GET/gt_customs/portal/cases

List customs cases of the signed-in customer company

Company is taken from the customer session. Inspection and hold dates, charge amounts and peer IRIs are never returned.

Parameters

NameInRequiredSchemaDescription
viewqueryNoany—
searchqueryNoany—
shipmentIdqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Cases with per-view counts
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "caseReference": null,
      "mrn": null,
      "blNumber": null,
      "containerNumbers": [
        "string"
      ],
      "shipmentId": null,
      "shipmentReference": null,
      "stepCode": "string",
      "steps": [
        {
          "code": "string"
        }
      ],
      "inspection": true,
      "missingDocuments": [
        {
          "kind": null,
          "label": "string",
          "blocking": true
        }
      ],
      "cleared": true,
      "releasedAt": null,
      "eta": null,
      "dutyStatus": "paid",
      "vatStatus": "paid",
      "documentCount": 1,
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "counts": {
    "key": 1
  }
}
401No customer session
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403No customs access for this user or company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_customs/portal/cases?view=all&page=1&pageSize=20" \
  -H "Accept: application/json"
GET/gt_customs/portal/cases/{id}

Customs case detail (customer)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Case
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "caseReference": null,
    "mrn": null,
    "blNumber": null,
    "containerNumbers": [
      "string"
    ],
    "shipmentId": null,
    "shipmentReference": null,
    "stepCode": "string",
    "steps": [
      {
        "code": "string"
      }
    ],
    "inspection": true,
    "missingDocuments": [
      {
        "kind": null,
        "label": "string",
        "blocking": true
      }
    ],
    "cleared": true,
    "releasedAt": null,
    "eta": null,
    "dutyStatus": "paid",
    "vatStatus": "paid",
    "documentCount": 1,
    "updatedAt": "string"
  }
}
403No customs access
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_customs/portal/cases/:id" \
  -H "Accept: application/json"

GT Deliveries

Showing 7 of 7 endpoints
GET/gt_deliveries/portal/calendar

Delivery calendar: day states for selected units and the company request chips (max 120 days)

Parameters

NameInRequiredSchemaDescription
fromqueryYesany—
toqueryYesany—
unitsqueryNoany—

Responses

200Calendar
Content-Type: application/json
{
  "ok": true,
  "today": "string",
  "days": [
    {
      "date": "string",
      "state": "free",
      "reason": null
    }
  ],
  "chips": [
    {
      "requestId": "string",
      "date": "string",
      "to": null,
      "window": "string",
      "status": "string",
      "confirmed": true,
      "direction": null,
      "shipmentId": "string",
      "referenceNumber": null,
      "containerNumbers": [
        "string"
      ]
    }
  ],
  "window": {
    "firstPossible": null,
    "freeUntil": null
  }
}
400Invalid range
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing deliveries area or feature
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_deliveries/portal/calendar?from=string&to=string" \
  -H "Accept: application/json"
POST/gt_deliveries/portal/requests

Request a delivery slot for units of the current company (one request per shipment)

Request body (application/json)

{
  "unitIds": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "mode": "date",
  "date": null,
  "from": null,
  "to": null,
  "window": "string",
  "address": "string",
  "contactName": "string",
  "contactPhone": "string",
  "driverNotes": null
}

Responses

201Requested
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "string",
      "status": "requested",
      "shipmentId": "string",
      "referenceNumber": null,
      "unitIds": [
        "string"
      ],
      "containerNumbers": [
        "string"
      ],
      "mode": "date",
      "requestedDate": null,
      "requestedFrom": null,
      "requestedTo": null,
      "excludedDates": [
        "string"
      ],
      "window": "string",
      "address": null,
      "contactName": null,
      "contactPhone": null,
      "driverNotes": null,
      "decisionNote": null,
      "confirmedDate": null,
      "confirmedWindow": null,
      "driver": null,
      "podAt": null,
      "outsideFreeTime": true,
      "updatedAt": "string",
      "canChange": true,
      "canCancel": true,
      "canReportNotArrived": true
    }
  ]
}
400Validation failed or day unavailable (localized `message`)
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing portal.deliveries.request
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Units not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
409Unit already requested or delivered
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_deliveries/portal/requests" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"unitIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ],
  \"mode\": \"date\",
  \"date\": null,
  \"from\": null,
  \"to\": null,
  \"window\": \"string\",
  \"address\": \"string\",
  \"contactName\": \"string\",
  \"contactPhone\": \"string\",
  \"driverNotes\": null
}"
PUT/gt_deliveries/portal/requests/{id}

Change or cancel an own delivery request while it awaits the desk decision (optimistic lock via `updatedAt`)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "action": "update",
  "updatedAt": "string"
}

Responses

200Updated
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "string",
    "status": "requested",
    "shipmentId": "string",
    "referenceNumber": null,
    "unitIds": [
      "string"
    ],
    "containerNumbers": [
      "string"
    ],
    "mode": "date",
    "requestedDate": null,
    "requestedFrom": null,
    "requestedTo": null,
    "excludedDates": [
      "string"
    ],
    "window": "string",
    "address": null,
    "contactName": null,
    "contactPhone": null,
    "driverNotes": null,
    "decisionNote": null,
    "confirmedDate": null,
    "confirmedWindow": null,
    "driver": null,
    "podAt": null,
    "outsideFreeTime": true,
    "updatedAt": "string",
    "canChange": true,
    "canCancel": true,
    "canReportNotArrived": true
  }
}
400Validation failed or day unavailable
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Request not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
409Stale version or request already decided
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_deliveries/portal/requests/:id" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"update\",
  \"updatedAt\": \"string\"
}"
POST/gt_deliveries/portal/requests/{id}/not-arrived

Report that the container did not arrive on the confirmed slot

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "updatedAt": "string",
  "note": null
}

Responses

200Reported
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "string",
    "status": "requested",
    "shipmentId": "string",
    "referenceNumber": null,
    "unitIds": [
      "string"
    ],
    "containerNumbers": [
      "string"
    ],
    "mode": "date",
    "requestedDate": null,
    "requestedFrom": null,
    "requestedTo": null,
    "excludedDates": [
      "string"
    ],
    "window": "string",
    "address": null,
    "contactName": null,
    "contactPhone": null,
    "driverNotes": null,
    "decisionNote": null,
    "confirmedDate": null,
    "confirmedWindow": null,
    "driver": null,
    "podAt": null,
    "outsideFreeTime": true,
    "updatedAt": "string",
    "canChange": true,
    "canCancel": true,
    "canReportNotArrived": true
  }
}
404Request not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
409Stale version or not yet due
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_deliveries/portal/requests/:id/not-arrived" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"updatedAt\": \"string\",
  \"note\": null
}"
GET/gt_deliveries/portal/units

Planner units of the current customer company (with request state, earliest date and free time)

Parameters

NameInRequiredSchemaDescription
shipmentqueryNoany—

Responses

200Units
Content-Type: application/json
{
  "ok": true,
  "today": "string",
  "items": [
    {
      "unitId": "string",
      "shipmentId": "string",
      "referenceNumber": "string",
      "clientReference": null,
      "direction": "string",
      "transportMode": null,
      "cargoType": null,
      "label": "string",
      "containerNumber": null,
      "firstPossible": null,
      "freeUntil": null,
      "freeDaysLeft": null,
      "outsideFreeTime": true,
      "plannedWithinFreeTime": true,
      "state": "todo",
      "view": "todo",
      "request": null
    }
  ],
  "counts": {
    "key": 1
  },
  "windows": [
    "string"
  ],
  "canRequest": true,
  "canSeeShipments": true,
  "canSeeDocuments": true
}
401No customer session
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing deliveries area or portal.deliveries.view
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_deliveries/portal/units" \
  -H "Accept: application/json"
GET/gt_deliveries/requests
Auth requiredgt_deliveries.view

List customer delivery requests (staff)

Requires features: gt_deliveries.view

Parameters

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

Responses

200Requests
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "companyName": null,
      "referenceNumber": null,
      "containerNumbers": [
        "string"
      ],
      "mode": "string",
      "requestedDate": null,
      "requestedFrom": null,
      "requestedTo": null,
      "window": "string",
      "status": "string",
      "confirmedDate": null,
      "confirmedWindow": null,
      "driverName": null,
      "truckPlate": null,
      "outsideFreeTime": true,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_deliveries/requests?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/gt_deliveries/requests
Auth requiredgt_deliveries.manage

Decide / progress a delivery request: accept (confirmed slot), reject (note), driver & plates, in delivery, delivered (POD). Optimistic lock via header.

Requires features: gt_deliveries.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "action": "accept"
}

Responses

200Updated
Content-Type: application/json
{
  "id": "string",
  "status": "string",
  "updatedAt": null
}
400Validation failed
Content-Type: application/json
{
  "error": "string"
}
409Optimistic lock conflict or invalid transition
Content-Type: application/json
{}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_deliveries/requests" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"action\": \"accept\"
}"

GT Documents

Showing 9 of 9 endpoints
GET/gt_documents/one-record/submissions/{id}/content

Download the file of a portal-held ft:DocumentSubmission LO (ONE Record peer with a GET grant)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File bytes
Content-Type: application/json
"string"
401No ONE Record token / session
Content-Type: application/json
{
  "error": "string"
}
403No access grant
Content-Type: application/json
{
  "error": "string"
}
404Unknown LO or no stored file
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/one-record/submissions/:id/content" \
  -H "Accept: application/json"
GET/gt_documents/portal/documents

List the customer company documents (by shipment / customs case), own uploads and missing documents

Parameters

NameInRequiredSchemaDescription
shipmentIdqueryNoany—
customsCaseIdqueryNoany—

Responses

200Documents
Content-Type: application/json
{
  "ok": true,
  "documents": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": null,
      "identifier": null,
      "type": null,
      "category": "transport",
      "commercial": true,
      "documentDate": null,
      "sources": [
        "shipment"
      ],
      "shipmentId": null,
      "shipmentReference": null,
      "customsCaseId": null,
      "customsCaseReference": null,
      "invoiceId": null,
      "contentUrl": "string"
    }
  ],
  "uploads": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "documentType": "string",
      "fileName": "string",
      "mimeType": null,
      "fileSize": null,
      "note": null,
      "status": "pending_review",
      "reviewNote": null,
      "shipmentId": null,
      "shipmentReference": null,
      "customsCaseId": null,
      "customsCaseReference": null,
      "createdAt": "string",
      "reviewedAt": null,
      "updatedAt": "string",
      "contentUrl": "string"
    }
  ],
  "missing": [
    {
      "kind": null,
      "label": "string",
      "uploadType": "string",
      "blocking": true,
      "caseId": "string",
      "caseReference": null
    }
  ],
  "missingCount": 1,
  "complete": true,
  "shipmentReference": null,
  "canUpload": true,
  "canViewFinance": true
}
401Not signed in
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing documents area or portal.documents.view
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/portal/documents" \
  -H "Accept: application/json"
GET/gt_documents/portal/documents/{id}/content

Open a document (proxied from the owning peer after the company link check)

Query `?download=1` forces a download. Accessible with portal.documents.view, or with portal.invoices.view for invoice PDFs.

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File bytes
Content-Type: application/json
"string"
403No documents / invoices access
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Not linked to this company, blocked, hidden or unknown
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
502Peer content unavailable
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/portal/documents/:id/content" \
  -H "Accept: application/json"
GET/gt_documents/portal/uploads

List the customer company uploads

Parameters

NameInRequiredSchemaDescription
shipmentIdqueryNoany—
customsCaseIdqueryNoany—

Responses

200Uploads
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "documentType": "string",
      "fileName": "string",
      "mimeType": null,
      "fileSize": null,
      "note": null,
      "status": "pending_review",
      "reviewNote": null,
      "shipmentId": null,
      "shipmentReference": null,
      "customsCaseId": null,
      "customsCaseReference": null,
      "createdAt": "string",
      "reviewedAt": null,
      "updatedAt": "string",
      "contentUrl": "string"
    }
  ],
  "canUpload": true
}
403Missing documents area or feature
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/portal/uploads" \
  -H "Accept: application/json"
POST/gt_documents/portal/uploads

Upload a document for GT verification (multipart: file, documentType, shipmentId and/or customsCaseId, note)

Max 20 MB; pdf, jpg, png, xlsx, docx, msg (content is sniffed). The upload starts as pending_review.

Request body (multipart/form-data)

documentType=commercial_invoice

Responses

201Created
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "documentType": "string",
    "fileName": "string",
    "mimeType": null,
    "fileSize": null,
    "note": null,
    "status": "pending_review",
    "reviewNote": null,
    "shipmentId": null,
    "shipmentReference": null,
    "customsCaseId": null,
    "customsCaseReference": null,
    "createdAt": "string",
    "reviewedAt": null,
    "updatedAt": "string",
    "contentUrl": "string"
  }
}
400Validation failed (fieldErrors.file: file_empty | file_type)
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing portal.documents.upload
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Shipment / customs case not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
413File larger than 20 MB
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_documents/portal/uploads" \
  -H "Accept: application/json" \
  -H "Content-Type: multipart/form-data" \
  -d "{
  \"documentType\": \"commercial_invoice\"
}"
GET/gt_documents/portal/uploads/{id}/content

Open one of the customer company uploads

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File bytes
Content-Type: application/json
"string"
404Not an upload of this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/portal/uploads/:id/content" \
  -H "Accept: application/json"
GET/gt_documents/uploads
Auth requiredgt_documents.uploads.view

List customer document uploads (staff review queue)

Requires features: gt_documents.uploads.view

Parameters

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

Responses

200Uploads
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "companyName": null,
      "shipmentReference": null,
      "customsCaseReference": null,
      "documentType": "string",
      "fileName": "string",
      "mimeType": null,
      "fileSize": null,
      "note": null,
      "status": "pending_review",
      "reviewedAt": null,
      "reviewNote": null,
      "previewUrl": "string",
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/uploads?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/gt_documents/uploads
Auth requiredgt_documents.uploads.review

Verify or reject a customer upload (reject requires a note; optimistic lock via updatedAt header)

Requires features: gt_documents.uploads.review

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "status": "verified",
  "reviewNote": null
}

Responses

200Updated
Content-Type: application/json
{
  "id": "string",
  "companyName": null,
  "shipmentReference": null,
  "customsCaseReference": null,
  "documentType": "string",
  "fileName": "string",
  "mimeType": null,
  "fileSize": null,
  "note": null,
  "status": "pending_review",
  "reviewedAt": null,
  "reviewNote": null,
  "previewUrl": "string",
  "createdAt": null,
  "updatedAt": null
}
409Optimistic lock conflict
Content-Type: application/json
{
  "code": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_documents/uploads" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"status\": \"verified\",
  \"reviewNote\": null
}"
GET/gt_documents/uploads/{id}/content
Auth requiredgt_documents.uploads.view

Preview / download a customer upload (staff)

Requires features: gt_documents.uploads.view

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File bytes
Content-Type: application/json
"string"
404Not found in the selected organization
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_documents/uploads/:id/content" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

GT Invoices

Showing 8 of 8 endpoints
GET/gt_invoices/inquiries
Auth requiredgt_invoices.view

List customer invoice inquiries (staff)

Requires features: gt_invoices.view

Parameters

NameInRequiredSchemaDescription
idqueryNoany—
statusqueryNoany—
kindqueryNoany—
searchqueryNoany—
pagequeryNoany—
pageSizequeryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—

Responses

200Inquiries
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "invoiceId": "string",
      "invoiceNumber": null,
      "companyName": null,
      "kind": "contact",
      "message": null,
      "paidOn": null,
      "attachmentUrl": null,
      "status": "submitted",
      "staffNote": null,
      "handledAt": null,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/inquiries?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/gt_invoices/inquiries
Auth requiredgt_invoices.inquiries.manage

Acknowledge / resolve an inquiry and add a staff note (optimistic lock via updatedAt header)

Requires features: gt_invoices.inquiries.manage

Request body (application/json)

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

Responses

200Updated
Content-Type: application/json
{
  "id": "string",
  "invoiceId": "string",
  "invoiceNumber": null,
  "companyName": null,
  "kind": "contact",
  "message": null,
  "paidOn": null,
  "attachmentUrl": null,
  "status": "submitted",
  "staffNote": null,
  "handledAt": null,
  "createdAt": null,
  "updatedAt": null
}
409Optimistic lock conflict
Content-Type: application/json
{
  "code": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_invoices/inquiries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"staffNote\": null
}"
GET/gt_invoices/one-record/inquiries/{id}/attachment

Download the attachment of a portal-held ft:InvoiceInquiry LO (ONE Record peer with a GET grant)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200File bytes
Content-Type: application/json
"string"
401No ONE Record token / session
Content-Type: application/json
{
  "error": "string"
}
403No access grant
Content-Type: application/json
{
  "error": "string"
}
404Unknown LO or no attachment
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/one-record/inquiries/:id/attachment" \
  -H "Accept: application/json"
GET/gt_invoices/portal/export

Export the current customer company invoices as CSV

Parameters

NameInRequiredSchemaDescription
viewqueryNoany—
searchqueryNoany—

Responses

200CSV file (UTF-8 with BOM, `;` separated)
Content-Type: application/json
"string"
403Missing invoices area or feature
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/portal/export?view=all" \
  -H "Accept: application/json"
GET/gt_invoices/portal/inquiries

List the current customer company invoice inquiries

Parameters

NameInRequiredSchemaDescription
invoiceIdqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Inquiries
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "invoiceId": "00000000-0000-4000-8000-000000000000",
      "invoiceNumber": null,
      "kind": "contact",
      "message": null,
      "paidOn": null,
      "hasAttachment": true,
      "status": "submitted",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ]
}
403Missing invoices area or feature
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/portal/inquiries?page=1&pageSize=50" \
  -H "Accept: application/json"
POST/gt_invoices/portal/inquiries

Submit an invoice contact request or payment notice (JSON or multipart with `file`)

Request body (application/json)

{
  "invoiceId": "00000000-0000-4000-8000-000000000000",
  "kind": "contact"
}

Responses

201Created
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "invoiceId": "00000000-0000-4000-8000-000000000000",
    "invoiceNumber": null,
    "kind": "contact",
    "message": null,
    "paidOn": null,
    "hasAttachment": true,
    "status": "submitted",
    "createdAt": "string",
    "updatedAt": "string"
  }
}
400Validation failed
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing portal.invoices.inquire
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Invoice not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
409Invoice already paid (payment notice)
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_invoices/portal/inquiries" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"invoiceId\": \"00000000-0000-4000-8000-000000000000\",
  \"kind\": \"contact\"
}"
GET/gt_invoices/portal/invoices

List the current customer company invoices (Finanse)

Parameters

NameInRequiredSchemaDescription
viewqueryNoany—
searchqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Invoices, view counts and the header summary
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "invoiceNumber": "string",
      "issueDate": null,
      "dueDate": null,
      "grossAmount": null,
      "currency": null,
      "status": "paid",
      "daysToDue": null,
      "ksefNumber": null,
      "folders": [
        {
          "reference": null,
          "shipmentId": null
        }
      ],
      "inquiries": {
        "key": {
          "id": "string",
          "status": "string",
          "createdAt": "string",
          "paidOn": null
        }
      }
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "counts": {
    "all": 1,
    "due": 1,
    "overdue": 1,
    "paid": 1
  },
  "summary": {
    "dueTotal": {
      "key": 1
    },
    "overdueTotal": {
      "key": 1
    },
    "overdueCount": 1,
    "onTimePct": null,
    "paymentTermDays": null
  },
  "canInquire": true
}
401Not signed in
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing invoices area or feature
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/portal/invoices?view=all&page=1&pageSize=20" \
  -H "Accept: application/json"
GET/gt_invoices/portal/invoices/{id}/pdf

Open the invoice PDF (redirects to the scoped document content proxy)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Success response
Content-Type: application/json
"string"
302Redirect to the document content
Content-Type: application/json
"string"
404No PDF for this invoice or not the customer's invoice
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_invoices/portal/invoices/:id/pdf" \
  -H "Accept: application/json"

GT Offers

Showing 6 of 6 endpoints
GET/gt_offers/order-requests
Auth requiredgt_offers.view

List order-from-offer requests (staff queue)

Requires features: gt_offers.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
statusqueryNoany—
companyIdqueryNoany—
searchqueryNoany—

Responses

200Order requests
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "companyName": null,
      "routeLabel": null,
      "status": "submitted",
      "createdFolderReference": null,
      "updatedAt": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_offers/order-requests?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
PUT/gt_offers/order-requests
Auth requiredgt_offers.manage

Accept (with the created FMS folder reference) or reject (with a note) an order request

Requires features: gt_offers.manage

Request body (application/json)

{
  "id": "00000000-0000-4000-8000-000000000000",
  "decision": "accept"
}

Responses

200Decided
Content-Type: application/json
{
  "id": "string",
  "companyName": null,
  "routeLabel": null,
  "status": "submitted",
  "createdFolderReference": null,
  "updatedAt": "string"
}
409Already decided or modified concurrently (optimistic lock)
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_offers/order-requests" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"decision\": \"accept\"
}"
GET/gt_offers/portal/offers

List the customer company offers (portal)

Parameters

NameInRequiredSchemaDescription
viewqueryNoany—
modequeryNoany—
searchqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Offers
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "origin": null,
      "destination": null,
      "carriers": [
        "string"
      ],
      "containerTypes": [
        "string"
      ],
      "transportMode": null,
      "validUntil": null,
      "daysLeft": null,
      "expired": true,
      "fromPrice": [
        {
          "amount": 1,
          "currency": "string"
        }
      ],
      "orders": {
        "pending": 1,
        "accepted": 1,
        "rejected": 1
      }
    }
  ],
  "total": 1,
  "counts": {
    "active": 1,
    "all": 1
  },
  "canOrder": true
}
401Not signed in
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403No access to offers
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_offers/portal/offers?view=active&page=1&pageSize=50" \
  -H "Accept: application/json"
GET/gt_offers/portal/offers/{id}

Customer offer detail with carrier variants and order requests (portal)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Offer
Content-Type: application/json
{
  "ok": true,
  "offer": {
    "id": "string"
  },
  "orderRequests": [
    {
      "id": "string",
      "status": "string"
    }
  ],
  "canOrder": true
}
404Unknown or another company offer
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_offers/portal/offers/:id" \
  -H "Accept: application/json"
GET/gt_offers/portal/order-requests

List the company order-from-offer requests (portal)

Parameters

NameInRequiredSchemaDescription
offerIdqueryNoany—

Responses

200Order requests
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "offerId": "00000000-0000-4000-8000-000000000000",
      "status": "submitted",
      "gtReference": null
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_offers/portal/order-requests" \
  -H "Accept: application/json"
POST/gt_offers/portal/order-requests

Submit an order from an offer (portal)

Request body (application/json)

{
  "offerId": "00000000-0000-4000-8000-000000000000",
  "containers": [],
  "commodity": "string",
  "insurance": false
}

Responses

201Submitted, awaiting GT acceptance
Content-Type: application/json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "offerId": "00000000-0000-4000-8000-000000000000",
    "status": "submitted",
    "gtReference": null
  }
}
400Invalid request or lane
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Ordering not allowed for this user
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
404Unknown or another company offer
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
409Offer expired
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_offers/portal/order-requests" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"offerId\": \"00000000-0000-4000-8000-000000000000\",
  \"containers\": [],
  \"commodity\": \"string\",
  \"insurance\": false
}"

GT Partners

Showing 20 of 23 endpoints
GET/gt_partners/agent/dashboard

Agent dashboard counts (open RFQs, bookings to confirm, departures due, shipments) (agent.dashboard.view)

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/dashboard" \
  -H "Accept: application/json"
GET/gt_partners/agent/rfqs

RFQs addressed to the callers agent company (view = open | all) (agent.rfq.view)

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/rfqs" \
  -H "Accept: application/json"
GET/gt_partners/agent/rfqs/{id}

RFQ detail with the companys own quotes (agent.rfq.view)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/rfqs/:id" \
  -H "Accept: application/json"
POST/gt_partners/agent/rfqs/{id}/quotes

Quote an RFQ → ft:AgentQuote (409 when withdrawn / closed / past due) (agent.rfq.quote)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "currency": "string",
  "validUntil": "string",
  "lines": [
    {
      "chargeCode": "string",
      "amount": 1,
      "unit": "PER_CONTAINER",
      "quantity": 1
    }
  ]
}

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Not possible in the current state (returns it)
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/agent/rfqs/:id/quotes" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"currency\": \"string\",
  \"validUntil\": \"string\",
  \"lines\": [
    {
      \"chargeCode\": \"string\",
      \"amount\": 1,
      \"unit\": \"PER_CONTAINER\",
      \"quantity\": 1
    }
  ]
}"
GET/gt_partners/agent/shipments

Origin shipments of the callers agent company (view = to_book | to_dispatch | dispatched | all) (agent.shipments.view)

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/shipments" \
  -H "Accept: application/json"
GET/gt_partners/agent/shipments/{id}

Origin shipment detail with confirmations and documents sent (agent.shipments.view)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/shipments/:id" \
  -H "Accept: application/json"
POST/gt_partners/agent/shipments/{id}/booking-confirmations

Confirm the carrier booking → ft:BookingConfirmation (agent.bookings.confirm)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "bookingNumber": "string"
}

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409Not possible in the current state (returns it)
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/agent/shipments/:id/booking-confirmations" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"bookingNumber\": \"string\"
}"
POST/gt_partners/agent/shipments/{id}/dispatch-confirmations

Confirm dispatch (cargo departed) → ft:DispatchConfirmation (agent.dispatch.confirm)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{
  "atd": "string",
  "transportDocumentType": "BL",
  "transportDocumentNumber": "string",
  "containers": []
}

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/agent/shipments/:id/dispatch-confirmations" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"atd\": \"string\",
  \"transportDocumentType\": \"BL\",
  \"transportDocumentNumber\": \"string\",
  \"containers\": []
}"
POST/gt_partners/agent/shipments/{id}/documents

Upload an origin document (multipart file + documentType) → ft:DocumentSubmission (agent.documents.upload)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not an agent session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/agent/shipments/:id/documents" \
  -H "Accept: application/json"
GET/gt_partners/agent/users

Agent company users, pending invitations and assignable roles (agent.users.manage)

Responses

200Users
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "string",
      "email": "string",
      "displayName": "string",
      "isActive": true,
      "lastLoginAt": null,
      "roles": [
        {
          "slug": "string",
          "name": "string"
        }
      ]
    }
  ]
}
403Not a agent session or no permission
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/agent/users" \
  -H "Accept: application/json"
POST/gt_partners/agent/users/invitations

Invite a colleague into the agent company (agent.users.manage)

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invited
Content-Type: application/json
{
  "ok": true,
  "inviteUrl": "string"
}
403Role of another audience / not a agent admin
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409E-mail already has a portal account
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/agent/users/invitations" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
DELETE/gt_partners/agent/users/invitations/{id}

Cancel a pending invitation of the agent company

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Cancelled
Content-Type: application/json
{
  "ok": true
}
404No such pending invitation
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/gt_partners/agent/users/invitations/:id" \
  -H "Accept: application/json"
GET/gt_partners/haulier/dashboard

Haulier dashboard counts (today, upcoming, in transit, POD missing) (haulier.dashboard.view)

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/haulier/dashboard" \
  -H "Accept: application/json"
GET/gt_partners/haulier/jobs

Haulage jobs of the callers company (view = today | upcoming | active | done | all) (haulier.jobs.view)

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/haulier/jobs" \
  -H "Accept: application/json"
GET/gt_partners/haulier/jobs/{id}

Haulage job detail with its events (haulier.jobs.view)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/haulier/jobs/:id" \
  -H "Accept: application/json"
POST/gt_partners/haulier/jobs/{id}/deliver

Confirm delivery → ft:HaulageEvent DELIVERED (409 when not picked up) (haulier.jobs.deliver)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/haulier/jobs/:id/deliver" \
  -H "Accept: application/json"
POST/gt_partners/haulier/jobs/{id}/pickup

Confirm pick-up → ft:HaulageEvent PICKED_UP (409 when not assigned) (haulier.jobs.pickup)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/haulier/jobs/:id/pickup" \
  -H "Accept: application/json"
POST/gt_partners/haulier/jobs/{id}/pod

Upload the POD (photo / PDF, multipart file) → ft:HaulageEvent POD_UPLOADED (haulier.pod.upload)

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

201OK
Content-Type: application/json
{
  "ok": true
}
403Not a haulier session or missing feature
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
404Not found in the caller company
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/haulier/jobs/:id/pod" \
  -H "Accept: application/json"
GET/gt_partners/haulier/users

Haulier company users, pending invitations and assignable roles (haulier.users.manage)

Responses

200Users
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "string",
      "email": "string",
      "displayName": "string",
      "isActive": true,
      "lastLoginAt": null,
      "roles": [
        {
          "slug": "string",
          "name": "string"
        }
      ]
    }
  ]
}
403Not a haulier session or no permission
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_partners/haulier/users" \
  -H "Accept: application/json"
POST/gt_partners/haulier/users/invitations

Invite a colleague into the haulier company (haulier.users.manage)

Request body (application/json)

{
  "email": "user@example.com",
  "roleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

201Invited
Content-Type: application/json
{
  "ok": true,
  "inviteUrl": "string"
}
403Role of another audience / not a haulier admin
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}
409E-mail already has a portal account
Content-Type: application/json
{
  "ok": false,
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_partners/haulier/users/invitations" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"roleIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"

GT Peers

Showing 8 of 8 endpoints
GET/gt_peers/connections
Auth requiredgt_peers.view

List federated peer connections

Requires features: gt_peers.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
searchqueryNoany—

Responses

200Peer connections
Content-Type: application/json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "name": "string",
      "role": "string",
      "baseIri": "string",
      "tokenUrl": "string",
      "clientId": "string",
      "hasClientSecret": true,
      "hasInboundSecret": true,
      "inboundPath": "string",
      "enabledTypes": [
        "string"
      ],
      "status": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/connections?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_peers/connections
Auth requiredgt_peers.manage

Create a peer connection

Requires features: gt_peers.manage

Request body (application/json)

{
  "code": "string",
  "name": "string",
  "role": "tms",
  "baseIri": "https://example.com/resource",
  "tokenUrl": "https://example.com/resource",
  "clientId": "string",
  "clientSecret": "string",
  "audience": null,
  "inboundSecret": null,
  "enabledTypes": [],
  "knownIris": [],
  "serviceCompany": null,
  "status": "active"
}

Responses

201Created
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "name": "string",
  "role": "string",
  "baseIri": "string",
  "tokenUrl": "string",
  "clientId": "string",
  "hasClientSecret": true,
  "hasInboundSecret": true,
  "inboundPath": "string",
  "enabledTypes": [
    "string"
  ],
  "status": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_peers/connections" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"name\": \"string\",
  \"role\": \"tms\",
  \"baseIri\": \"https://example.com/resource\",
  \"tokenUrl\": \"https://example.com/resource\",
  \"clientId\": \"string\",
  \"clientSecret\": \"string\",
  \"audience\": null,
  \"inboundSecret\": null,
  \"enabledTypes\": [],
  \"knownIris\": [],
  \"serviceCompany\": null,
  \"status\": \"active\"
}"
PUT/gt_peers/connections
Auth requiredgt_peers.manage

Update a peer connection (empty secrets keep the stored value; changing the baseIri/tokenUrl origin requires a new clientSecret)

Requires features: gt_peers.manage

Request body (application/json)

{
  "audience": null,
  "inboundSecret": null,
  "serviceCompany": null,
  "id": "00000000-0000-4000-8000-000000000000"
}

Responses

200Updated
Content-Type: application/json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "name": "string",
  "role": "string",
  "baseIri": "string",
  "tokenUrl": "string",
  "clientId": "string",
  "hasClientSecret": true,
  "hasInboundSecret": true,
  "inboundPath": "string",
  "enabledTypes": [
    "string"
  ],
  "status": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_peers/connections" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"audience\": null,
  \"inboundSecret\": null,
  \"serviceCompany\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/gt_peers/connections
Auth requiredgt_peers.manage

Soft-delete a peer connection

Requires features: gt_peers.manage

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/gt_peers/connections" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_peers/connections/{id}/sync
Auth requiredgt_peers.manage

Queue discovery + refresh of a peer connection

Requires features: gt_peers.manage

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Request body (application/json)

{}

Responses

202Reconciliation queued
Content-Type: application/json
{
  "ok": true,
  "queued": true
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_peers/connections/:id/sync" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
POST/gt_peers/inbound/{connectionId}

Receive a signed ONE Record notification from a federated peer

Parameters

NameInRequiredSchemaDescription
connectionIdpathYesany—

Responses

204Accepted; the object is queued for fetch

No response body.

400Malformed notification body
Content-Type: application/json
{}
401Unknown connection, invalid or stale signature
Content-Type: application/json
{}
422Notified IRI does not belong to this peer
Content-Type: application/json
{}
503Notification could not be queued; retry later
Content-Type: application/json
{}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_peers/inbound/:connectionId" \
  -H "Accept: application/json"
GET/gt_peers/objects
Auth requiredgt_peers.view

List locally cached Logistics Objects

Requires features: gt_peers.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
peerIdqueryNoany—
loTypequeryNoany—
statusqueryNoany—
searchqueryNoany—

Responses

200Remote objects
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "iri": "string",
      "loType": "string",
      "status": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_peers/objects?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_peers/objects/fetch
Auth requiredgt_peers.manage

Fetch one Logistics Object from a peer immediately

Requires features: gt_peers.manage

Request body (application/json)

{
  "connectionId": "00000000-0000-4000-8000-000000000000",
  "iri": "https://example.com/resource"
}

Responses

200Fetch result
Content-Type: application/json
{
  "ok": true,
  "result": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_peers/objects/fetch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"connectionId\": \"00000000-0000-4000-8000-000000000000\",
  \"iri\": \"https://example.com/resource\"
}"

GT Portal

Showing 7 of 7 endpoints
GET/gt_portal/news
Auth requiredgt_portal.news.view

List news posts (staff)

Requires features: gt_portal.news.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
idqueryNoany—
searchqueryNoany—

Responses

200Posts
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "category": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_portal/news?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/gt_portal/news
Auth requiredgt_portal.news.manage

Create a news post

Requires features: gt_portal.news.manage

Request body (application/json)

{
  "title": "string",
  "body": "",
  "category": "gt",
  "publishedAt": null,
  "pinned": false,
  "serviceCompany": null,
  "audienceCompanyIds": []
}

Responses

201Created
Content-Type: application/json
{
  "id": "string",
  "title": "string",
  "category": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_portal/news" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"title\": \"string\",
  \"body\": \"\",
  \"category\": \"gt\",
  \"publishedAt\": null,
  \"pinned\": false,
  \"serviceCompany\": null,
  \"audienceCompanyIds\": []
}"
PUT/gt_portal/news
Auth requiredgt_portal.news.manage

Update a news post

Requires features: gt_portal.news.manage

Request body (application/json)

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

Responses

200Updated
Content-Type: application/json
{
  "id": "string",
  "title": "string",
  "category": "string"
}

Example

curl -X PUT "https://portal.gt.freighttech.org/api/gt_portal/news" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"publishedAt\": null,
  \"serviceCompany\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
DELETE/gt_portal/news
Auth requiredgt_portal.news.manage

Delete a news post

Requires features: gt_portal.news.manage

Responses

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

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/gt_portal/news" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_portal/portal/dashboard

Pulpit aggregate for the current customer (sections gated by role and company areas)

Responses

200Dashboard
Content-Type: application/json
{
  "company": {
    "displayName": "string"
  }
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_portal/portal/dashboard" \
  -H "Accept: application/json"
GET/gt_portal/portal/news

Portal news feed for the current customer

Responses

200Posts
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "title": "string"
    }
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_portal/portal/news" \
  -H "Accept: application/json"

GT Reports

Showing 2 of 2 endpoints
GET/gt_reports/portal/export

Download the report of the customer session company as an Excel workbook (.xlsx, one sheet per tab)

Parameters

NameInRequiredSchemaDescription
fromqueryNoany—
toqueryNoany—
groupByqueryNoany—

Responses

200application/vnd.openxmlformats-officedocument.spreadsheetml.sheet workbook (.xlsx)
Content-Type: application/json
"string"
400Invalid period
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
401No customer session
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing reports area or portal.reports.view
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_reports/portal/export?groupBy=month" \
  -H "Accept: application/json"
GET/gt_reports/portal/summary

Report summary (turnover, shipments, TEU, AIR, on-time %, CO₂) for the customer session company

Parameters

NameInRequiredSchemaDescription
fromqueryNoany—
toqueryNoany—
groupByqueryNoany—

Responses

200Report computed on demand
Content-Type: application/json
{
  "ok": true,
  "period": {
    "from": "string",
    "to": "string",
    "groupBy": "month",
    "wholeCooperation": true
  },
  "buckets": [
    "string"
  ],
  "kpis": {
    "turnoverNet": {
      "key": 1
    },
    "turnoverGross": {
      "key": 1
    },
    "primaryCurrency": null,
    "invoices": 1,
    "shipments": 1,
    "containers": 1,
    "teu": 1,
    "airKg": 1,
    "airShipments": 1,
    "lclShipments": 1,
    "lclCbm": null,
    "onTimePct": null,
    "paidInvoices": 1,
    "co2Kg": 1
  },
  "series": {
    "turnover": [
      {
        "key": "string",
        "net": {
          "key": 1
        },
        "gross": {
          "key": 1
        },
        "invoices": 1
      }
    ],
    "shipments": [
      {
        "key": "string",
        "total": 1,
        "byMode": {
          "OCEAN": 1,
          "AIR": 1,
          "ROAD": 1,
          "RAIL": 1,
          "OTHER": 1
        },
        "imports": 1,
        "exports": 1,
        "lcl": 1,
        "lclCbm": null
      }
    ],
    "teu": [
      {
        "key": "string",
        "containers": 1,
        "teu": 1,
        "c20": 1,
        "c40": 1,
        "unknownType": 1
      }
    ],
    "air": [
      {
        "key": "string",
        "shipments": 1,
        "kg": 1,
        "withoutWeight": 1
      }
    ],
    "onTimePct": [
      {
        "key": "string",
        "paid": 1,
        "onTime": 1,
        "pct": null,
        "overdueOpen": 1
      }
    ],
    "co2": [
      {
        "key": "string",
        "kg": 1,
        "byMode": {
          "OCEAN": 1,
          "AIR": 1,
          "ROAD": 1,
          "RAIL": 1,
          "OTHER": 1
        },
        "estimated": 1,
        "notEstimated": 1
      }
    ]
  },
  "breakdown": {
    "byMode": [
      {
        "mode": "string",
        "count": 1
      }
    ],
    "turnoverByMode": [
      {
        "mode": "string",
        "net": {
          "key": 1
        },
        "gross": {
          "key": 1
        },
        "invoices": 1
      }
    ],
    "byDirection": [
      {
        "direction": "string",
        "count": 1
      }
    ],
    "co2ByMode": [
      {
        "mode": "string",
        "kg": 1,
        "shipments": 1
      }
    ],
    "topRoutes": [
      {
        "originCode": null,
        "destinationCode": null,
        "count": 1
      }
    ],
    "currencies": [
      "string"
    ],
    "co2Rows": [
      {
        "shipmentId": "string",
        "referenceNumber": "string",
        "mode": "string",
        "originCode": null,
        "destinationCode": null,
        "distanceKm": null,
        "tonnes": null,
        "basis": null,
        "factor": null,
        "kg": null,
        "reason": null
      }
    ]
  },
  "coverage": {
    "shipments": 1,
    "undated": 1,
    "airWithoutWeight": 1,
    "lclWithoutVolume": 1,
    "containersUnknownType": 1,
    "co2NotEstimated": 1
  },
  "empty": true,
  "source": "listForReports"
}
400Invalid period
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
401No customer session
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Missing reports area or portal.reports.view
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_reports/portal/summary?groupBy=month" \
  -H "Accept: application/json"

GT Shipments

Showing 8 of 8 endpoints
GET/gt_shipments/maplibre/{file}

MapLibre GL worker module (static library file for the portal map)

Parameters

NameInRequiredSchemaDescription
filepathYesany—

Responses

200JavaScript module
Content-Type: application/json
"string"
404Unknown file
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/maplibre/:file" \
  -H "Accept: application/json"
GET/gt_shipments/portal/export

Export the current shipments view as CSV

Parameters

NameInRequiredSchemaDescription
directionqueryNoany—
viewqueryNoany—
searchqueryNoany—
filterqueryNoany—
modequeryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—

Responses

200CSV file
Content-Type: application/json
"string"

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/portal/export?direction=import&view=all" \
  -H "Accept: application/json"
GET/gt_shipments/portal/goods

Customer goods (packing-list items) grouped by SKU and by shipment

Parameters

NameInRequiredSchemaDescription
searchqueryNoany—

Responses

200Goods
Content-Type: application/json
{
  "ok": true,
  "products": [
    {}
  ],
  "shipments": [
    {}
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/portal/goods" \
  -H "Accept: application/json"
GET/gt_shipments/portal/map

Active customer shipments with map geometry (position, travelled/remaining route)

Responses

200Active shipments
Content-Type: application/json
{
  "ok": true,
  "items": [
    {}
  ]
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/portal/map" \
  -H "Accept: application/json"
GET/gt_shipments/portal/shipments

Customer shipments (current company) with view counts

Parameters

NameInRequiredSchemaDescription
directionqueryNoany—
viewqueryNoany—
searchqueryNoany—
filterqueryNoany—
modequeryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
pagequeryNoany—
pageSizequeryNoany—

Responses

200Shipments page
Content-Type: application/json
{
  "ok": true,
  "items": [
    {
      "id": "string",
      "referenceNumber": "string",
      "direction": "string",
      "transportMode": null,
      "statusCode": "string",
      "primaryReference": null,
      "eta": null,
      "etd": null,
      "etaDeviationDays": null,
      "holdPresent": true
    }
  ],
  "total": 1,
  "totalPages": 1,
  "counts": {
    "key": 1
  }
}
401No customer session
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}
403Role or company area does not allow shipments
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/portal/shipments?direction=import&view=all&page=1&pageSize=50" \
  -H "Accept: application/json"
GET/gt_shipments/portal/shipments/{id}

Customer shipment detail (teczka): units, legs, items, timeline

Parameters

NameInRequiredSchemaDescription
idpathYesany—

Responses

200Shipment detail
Content-Type: application/json
{
  "ok": true,
  "shipment": {},
  "units": [
    {}
  ],
  "timeline": [
    {}
  ]
}
404Not found for this company
Content-Type: application/json
{
  "ok": true,
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/portal/shipments/:id" \
  -H "Accept: application/json"
POST/gt_shipments/reproject
Auth requiredgt_shipments.manage

Re-project portal shipments from cached FMS folders

Requires features: gt_shipments.manage

Responses

200Projection stats
Content-Type: application/json
{
  "ok": true,
  "total": 1,
  "projected": 1,
  "deleted": 1,
  "skipped": 1
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/gt_shipments/reproject" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
GET/gt_shipments/shipments
Auth requiredgt_shipments.view

List projected portal shipments (staff diagnostics, incl. unmatched)

Requires features: gt_shipments.view

Parameters

NameInRequiredSchemaDescription
pagequeryNoany—
pageSizequeryNoany—
sortFieldqueryNoany—
sortDirqueryNoany—
searchqueryNoany—
matchedqueryNoany—
companyIdqueryNoany—
statusCodequeryNoany—

Responses

200Shipments
Content-Type: application/json
{
  "items": [
    {
      "id": "string",
      "referenceNumber": "string",
      "customerCompanyId": null,
      "statusCode": "string"
    }
  ],
  "total": 1
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/gt_shipments/shipments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Perspectives

Showing 4 of 4 endpoints
GET/perspectives/{tableId}
Auth requiredperspectives.use

Load perspectives for a table

Returns personal perspectives and available role defaults for the requested table identifier. Requires features: perspectives.use

Parameters

NameInRequiredSchemaDescription
tableIdpathYesany—

Responses

200Current perspectives and defaults.
Content-Type: application/json
{
  "tableId": "string",
  "perspectives": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "tableId": "string",
      "settings": {},
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null
    }
  ],
  "defaultPerspectiveId": null,
  "rolePerspectives": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "tableId": "string",
      "settings": {},
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null,
      "roleId": "00000000-0000-4000-8000-000000000000",
      "tenantId": null,
      "organizationId": null,
      "roleName": null
    }
  ],
  "manageableRolePerspectives": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "tableId": "string",
      "settings": {},
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null,
      "roleId": "00000000-0000-4000-8000-000000000000",
      "tenantId": null,
      "organizationId": null,
      "roleName": null
    }
  ],
  "roles": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "hasPerspective": true,
      "hasDefault": true
    }
  ],
  "canApplyToRoles": true
}
400Invalid table identifier
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/perspectives/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
POST/perspectives/{tableId}
Auth requiredperspectives.use

Create or update a perspective

Saves a personal perspective and optionally applies the same configuration to selected roles. Requires features: perspectives.use

Parameters

NameInRequiredSchemaDescription
tableIdpathYesany—

Request body (application/json)

{
  "name": "string",
  "settings": {}
}

Responses

200Perspective saved successfully.
Content-Type: application/json
{
  "perspective": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "tableId": "string",
    "settings": {},
    "isDefault": true,
    "createdAt": "string",
    "updatedAt": null
  },
  "rolePerspectives": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "tableId": "string",
      "settings": {},
      "isDefault": true,
      "createdAt": "string",
      "updatedAt": null,
      "roleId": "00000000-0000-4000-8000-000000000000",
      "tenantId": null,
      "organizationId": null,
      "roleName": null
    }
  ],
  "clearedRoleIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
400Validation failed or invalid roles provided
Content-Type: application/json
{
  "error": "string"
}
409Optimistic lock conflict or perspective name already exists
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X POST "https://portal.gt.freighttech.org/api/perspectives/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"settings\": {}
}"
DELETE/perspectives/{tableId}/{perspectiveId}
Auth requiredperspectives.use

Delete a personal perspective

Removes a perspective owned by the current user for the given table. Requires features: perspectives.use

Parameters

NameInRequiredSchemaDescription
tableIdpathYesany—
perspectiveIdpathYesany—

Responses

200Perspective removed.
Content-Type: application/json
{
  "success": true
}
400Invalid identifiers supplied
Content-Type: application/json
{
  "error": "string"
}
404Perspective not found
Content-Type: application/json
{
  "error": "string"
}
409Optimistic lock conflict
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/perspectives/string/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
DELETE/perspectives/{tableId}/roles/{roleId}
Auth requiredperspectives.role_defaults

Clear role perspectives for a table

Removes all role-level perspectives associated with the provided role identifier for the table. Requires features: perspectives.role_defaults

Parameters

NameInRequiredSchemaDescription
tableIdpathYesany—
roleIdpathYesany—

Request body (application/json)

"string"

Responses

200Role perspectives cleared.
Content-Type: application/json
{
  "success": true
}
400Invalid identifiers supplied
Content-Type: application/json
{
  "error": "string"
}
404Role not found in scope
Content-Type: application/json
{
  "error": "string"
}
409Optimistic lock conflict
Content-Type: application/json
{
  "error": "string"
}

Example

curl -X DELETE "https://portal.gt.freighttech.org/api/perspectives/string/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"

Query Index

Showing 3 of 3 endpoints
POST/query_index/purge
Auth requiredquery_index.purge

Purge query index records

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

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredquery_index.reindex

Trigger query index rebuild

Queues a reindex job for the specified entity type within the current tenant scope. Requires features: query_index.reindex

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"
}

Example

curl -X POST "https://portal.gt.freighttech.org/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 requiredquery_index.status.view

Inspect query index coverage

Returns entity counts comparing base tables with the query index along with the latest job status. Requires features: query_index.status.view

Responses

200Current query index status.
Content-Type: application/json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "baseCount": null,
      "indexCount": null,
      "vectorCount": null,
      "ok": true,
      "job": {
        "status": "idle",
        "startedAt": null,
        "finishedAt": null,
        "heartbeatAt": null,
        "processedCount": null,
        "totalCount": null,
        "scope": 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"
}

Example

curl -X GET "https://portal.gt.freighttech.org/api/query_index/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"