# Open Mercato API

Version: 0.4.8

Auto-generated OpenAPI definition for all enabled modules.

## Servers
- https://apiv2.tronergy.io – Default environment

## DELETE `/api_keys/keys`

Delete API key

Removes an API key by identifier. The key must belong to the current tenant and fall within the requester organization scope.

Requires features: api_keys.delete

**Tags:** API Keys

**Requires authentication.**

**Features:** api_keys.delete

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. API key identifier to delete |

### Responses

**200** – Key deleted successfully

Content-Type: `application/json`

```json
{
  "success": true
}
```

**400** – Missing or invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Key not found within scope

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/api_keys/keys?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/api_keys/keys`

List API keys

Returns paginated API keys visible to the current user, including per-key role assignments and organization context.

Requires features: api_keys.view

**Tags:** API Keys

**Requires authentication.**

**Features:** api_keys.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |

### Responses

**200** – Collection of API keys

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "string",
      "name": "string",
      "description": null,
      "keyPrefix": "string",
      "organizationId": null,
      "organizationName": null,
      "createdAt": "string",
      "lastUsedAt": null,
      "expiresAt": null,
      "roles": [
        {
          "id": "string",
          "name": null
        }
      ]
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

**400** – Tenant context missing

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/api_keys/keys" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/api_keys/keys`

Create API key

Creates a new API key, returning the one-time secret value together with the generated key prefix and scope details.

Requires features: api_keys.create

**Tags:** API Keys

**Requires authentication.**

**Features:** api_keys.create

### Request Body

Content-Type: `application/json`

```json
{
  "name": "string",
  "description": null,
  "tenantId": null,
  "organizationId": null,
  "roles": [],
  "expiresAt": null
}
```

### Responses

**201** – API key created successfully

Content-Type: `application/json`

```json
{
  "id": "string",
  "name": "string",
  "keyPrefix": "string",
  "tenantId": null,
  "organizationId": null,
  "roles": [
    {
      "id": "string",
      "name": null
    }
  ]
}
```

**400** – Invalid payload or missing tenant context

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/api_keys/keys" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"description\": null,
  \"tenantId\": null,
  \"organizationId\": null,
  \"roles\": [],
  \"expiresAt\": null
}"
```

## DELETE `/attachments`

Delete attachment

Removes an uploaded attachment and deletes the stored asset.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required |

### Responses

**200** – Attachment deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing attachment identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachment not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/attachments?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/attachments`

List attachments for a record

Returns uploaded attachments for the given entity record, ordered by newest first.

Requires features: attachments.view

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Required. Entity identifier that owns the attachments |
| recordId | query | any | Required. Record identifier within the entity |

### Responses

**200** – Attachments found for the record

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "string",
      "url": "string",
      "fileName": "string",
      "fileSize": 1,
      "createdAt": "string",
      "mimeType": null,
      "content": null
    }
  ]
}
```

**400** – Missing entity or record identifiers

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/attachments?entityId=string&recordId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/attachments`

Upload attachment

Uploads a new attachment using multipart form-data and stores metadata for later retrieval.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Request Body

Content-Type: `multipart/form-data`

```text
entityId=string
recordId=string
file=string
```

### Responses

**200** – Attachment stored successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "item": {
    "id": "string",
    "url": "string",
    "fileName": "string",
    "fileSize": 1,
    "content": null
  }
}
```

**400** – Payload validation error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: multipart/form-data" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"file\": \"string\"
}"
```

## 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.

**Tags:** Attachments

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – File content with appropriate MIME type

Content-Type: `application/json`

**400** – Missing attachment ID

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**401** – Unauthorized - authentication required for private partitions

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - insufficient permissions

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachment or file not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Partition misconfigured

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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).

**Tags:** Attachments

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |
| slug | path | any | Optional |

### Responses

**200** – Binary image content (Content-Type: image/jpeg, image/png, etc.)

Content-Type: `application/json`

**400** – Invalid parameters, missing ID, or non-image attachment

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**401** – Unauthorized - authentication required for private partitions

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - insufficient permissions

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Image not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Partition misconfigured or image rendering failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/attachments/image/:id/:slug" \
  -H "Accept: application/json"
```

## GET `/attachments/library`

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

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional. Page number for pagination |
| pageSize | query | any | Optional. Number of items per page (max 100) |
| search | query | any | Optional. Search by file name (case-insensitive) |
| partition | query | any | Optional. Filter by partition code |
| tags | query | any | Optional. Filter by tags (comma-separated) |
| sortField | query | any | Optional. Field to sort by |
| sortDir | query | any | Optional. Sort direction |

### Responses

**200** – Attachments list with pagination and metadata

Content-Type: `application/json`

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

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/attachments/library?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/attachments/library/{id}`

Delete attachment

Permanently deletes an attachment file from storage and database. Emits CRUD side effects.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Attachment deleted successfully

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid attachment ID

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachment not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/attachments/library/{id}`

Get attachment details

Returns complete details of an attachment including metadata, tags, assignments, and custom fields.

Requires features: attachments.view

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Attachment details

Content-Type: `application/json`

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

**400** – Invalid attachment ID

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachment not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PATCH `/attachments/library/{id}`

Update attachment metadata

Updates attachment tags, assignments, and custom fields. Emits CRUD side effects for indexing and events.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Attachment updated successfully

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload or attachment ID

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachment not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to save attributes

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PATCH "https://apiv2.tronergy.io/attachments/library/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## DELETE `/attachments/partitions`

Delete partition

Deletes a partition. Default partitions cannot be deleted. Partitions with existing attachments cannot be deleted.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Responses

**200** – Partition deleted successfully

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid ID or default partition deletion attempt

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Partition not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Partition in use

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/attachments/partitions`

List all attachment partitions

Returns all configured attachment partitions with storage settings, OCR configuration, and access control settings.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Responses

**200** – List of partitions

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "title": "string",
      "description": null,
      "isPublic": true,
      "requiresOcr": true,
      "ocrModel": null,
      "createdAt": null,
      "updatedAt": null,
      "envKey": "string"
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/attachments/partitions`

Create new partition

Creates a new attachment partition with specified storage and OCR settings. Requires unique partition code.

Requires features: attachments.manage

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Request Body

Content-Type: `application/json`

```json
{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null
}
```

### Responses

**201** – Partition created successfully

Content-Type: `application/json`

```json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
```

**400** – Invalid payload or partition code

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Partition code already exists

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null
}"
```

## PUT `/attachments/partitions`

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

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Request Body

Content-Type: `application/json`

```json
{
  "code": "string",
  "title": "string",
  "description": null,
  "ocrModel": null,
  "id": "00000000-0000-4000-8000-000000000000"
}
```

### Responses

**200** – Partition updated successfully

Content-Type: `application/json`

```json
{
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "code": "string",
    "title": "string",
    "description": null,
    "isPublic": true,
    "requiresOcr": true,
    "ocrModel": null,
    "createdAt": null,
    "updatedAt": null,
    "envKey": "string"
  }
}
```

**400** – Invalid payload or code change attempt

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Partition not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/attachments/partitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"title\": \"string\",
  \"description\": null,
  \"ocrModel\": null,
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## POST `/attachments/transfer`

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

**Tags:** Attachments

**Requires authentication.**

**Features:** attachments.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Attachments transferred successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "updated": 1
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Attachments not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Attachment model missing

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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\"
}"
```

## GET `/audit_logs/audit-logs/access`

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

**Tags:** Audit & Action Logs

**Requires authentication.**

**Features:** audit_logs.view_self

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| organizationId | query | any | Optional. Limit results to a specific organization |
| actorUserId | query | any | Optional. Filter by actor user id (tenant administrators only) |
| resourceKind | query | any | Optional. Restrict to a resource kind such as `order` or `product` |
| accessType | query | any | Optional. Access type filter, e.g. `read` or `export` |
| page | query | any | Optional. Page number (default 1) |
| pageSize | query | any | Optional. Page size (default 50) |
| limit | query | any | Optional. Explicit maximum number of records when paginating manually |
| before | query | any | Optional. Return logs created before this ISO-8601 timestamp |
| after | query | any | Optional. Return logs created after this ISO-8601 timestamp |

### Responses

**200** – Access logs returned successfully

Content-Type: `application/json`

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

**400** – Invalid filters supplied

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/audit_logs/audit-logs/access" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/audit_logs/audit-logs/actions`

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

**Tags:** Audit & Action Logs

**Requires authentication.**

**Features:** audit_logs.view_self

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| organizationId | query | any | Optional. Limit results to a specific organization |
| actorUserId | query | any | Optional. Filter logs created by a specific actor (tenant administrators only) |
| resourceKind | query | any | Optional. Filter by resource kind (e.g., "order", "product") |
| resourceId | query | any | Optional. Filter by resource ID (UUID of the specific record) |
| includeRelated | query | any | Optional. When `true`, also returns changes to child entities linked via parentResourceKind/parentResourceId |
| undoableOnly | query | any | Optional. When `true`, only undoable actions are returned |
| limit | query | any | Optional. Maximum number of records to return (default 50) |
| before | query | any | Optional. Return actions created before this ISO-8601 timestamp |
| after | query | any | Optional. Return actions created after this ISO-8601 timestamp |

### Responses

**200** – Action logs retrieved successfully

Content-Type: `application/json`

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

**400** – Invalid filter values

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/audit_logs/audit-logs/actions?includeRelated=false&undoableOnly=false" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/audit_logs/audit-logs/actions/redo`

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

**Tags:** Audit & Action Logs

**Requires authentication.**

**Features:** audit_logs.redo_self

### Request Body

Content-Type: `application/json`

```json
{
  "logId": "string"
}
```

### Responses

**200** – Redo executed successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "logId": null,
  "undoToken": null
}
```

**400** – Log not eligible for redo

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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`

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

**Tags:** Audit & Action Logs

**Requires authentication.**

**Features:** audit_logs.undo_self

### Request Body

Content-Type: `application/json`

```json
{
  "undoToken": "string"
}
```

### Responses

**200** – Undo applied successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "logId": "string"
}
```

**400** – Invalid or unavailable undo token

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/audit_logs/audit-logs/actions/undo" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"undoToken\": \"string\"
}"
```

## GET `/auth/admin/nav`

Resolve sidebar entries

Returns the backend navigation tree available to the authenticated administrator after applying role and personal sidebar preferences.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Responses

**200** – Sidebar navigation structure

Content-Type: `application/json`

```json
{
  "groups": [
    {
      "id": "string",
      "name": "string",
      "defaultName": "string",
      "items": [
        {
          "href": "string",
          "title": "string",
          "defaultTitle": "string",
          "enabled": true
        }
      ]
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/admin/nav" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/auth/feature-check`

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.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Request Body

Content-Type: `application/json`

```json
{
  "features": [
    "string"
  ]
}
```

### Responses

**200** – Evaluation result

Content-Type: `application/json`

```json
{
  "ok": true,
  "granted": [
    "string"
  ],
  "userId": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/feature-check" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"features\": [
    \"string\"
  ]
}"
```

## GET `/auth/features`

List declared feature flags

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

Requires features: auth.acl.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.acl.manage

### Responses

**200** – Aggregated feature catalog

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "module": "string"
    }
  ],
  "modules": [
    {
      "id": "string",
      "title": "string"
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/features" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/auth/locale`

GET /auth/locale

**Tags:** Authentication & Accounts

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/locale" \
  -H "Accept: application/json"
```

## POST `/auth/locale`

POST /auth/locale

**Tags:** Authentication & Accounts

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/locale" \
  -H "Accept: application/json"
```

## POST `/auth/login`

Authenticate user credentials

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

**Tags:** Authentication & Accounts

### Request Body

Content-Type: `application/x-www-form-urlencoded`

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

### Responses

**200** – Authentication succeeded

Content-Type: `application/json`

```json
{
  "ok": true,
  "token": "string",
  "redirect": null
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Invalid credentials

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – User lacks required role

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**429** – Too many login attempts

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/login" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=user%40example.com&password=string"
```

## GET `/auth/logout`

Log out (legacy GET)

For convenience, the GET variant performs the same logout logic as POST and issues a redirect.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Responses

**200** – Success response

Content-Type: `application/json`

**302** – Redirect to login after successful logout

Content-Type: `text/html`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/auth/logout`

Invalidate session and redirect

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

**Tags:** Authentication & Accounts

**Requires authentication.**

### Responses

**201** – Success response

Content-Type: `application/json`

**302** – Redirect to login after successful logout

Content-Type: `text/html`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/logout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/auth/profile`

Get current profile

Returns the email address for the signed-in user.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Responses

**200** – Profile payload

Content-Type: `application/json`

```json
{
  "email": "user@example.com",
  "roles": [
    "string"
  ]
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/profile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/auth/profile`

Update current profile

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

**Tags:** Authentication & Accounts

**Requires authentication.**

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Profile updated

Content-Type: `application/json`

```json
{
  "ok": true,
  "email": "user@example.com"
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Authentication & Accounts

### Request Body

Content-Type: `application/x-www-form-urlencoded`

```text
email=user%40example.com
```

### Responses

**200** – Reset email dispatched (or ignored for unknown accounts)

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**429** – Too many password reset requests

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Authentication & Accounts

### Request Body

Content-Type: `application/x-www-form-urlencoded`

```text
token=string&password=string
```

### Responses

**200** – Password reset succeeded

Content-Type: `application/json`

```json
{
  "ok": true,
  "redirect": "string"
}
```

**400** – Invalid token or payload

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**429** – Too many reset confirmation attempts

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/reset/confirm" \
  -H "Accept: application/json" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=string&password=string"
```

## DELETE `/auth/roles`

Delete role

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

Requires features: auth.roles.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.roles.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Role identifier |

### Responses

**200** – Role deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Role cannot be deleted

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/auth/roles?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/auth/roles`

List roles

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

Requires features: auth.roles.list

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.roles.list

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| tenantId | query | any | Optional |

### Responses

**200** – Role collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "usersCount": 1,
      "tenantId": null,
      "tenantName": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/roles?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/auth/roles`

Create role

Creates a new role for the current tenant or globally when `tenantId` is omitted.

Requires features: auth.roles.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.roles.manage

### Request Body

Content-Type: `application/json`

```json
{
  "name": "string",
  "tenantId": null
}
```

### Responses

**201** – Role created

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"tenantId\": null
}"
```

## PUT `/auth/roles`

Update role

Updates mutable fields on an existing role.

Requires features: auth.roles.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.roles.manage

### Request Body

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "tenantId": null
}
```

### Responses

**200** – Role updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/auth/roles" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": null
}"
```

## GET `/auth/roles/acl`

Fetch role ACL

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

Requires features: auth.acl.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.acl.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| roleId | query | any | Required |
| tenantId | query | any | Optional |

### Responses

**200** – Role ACL entry

Content-Type: `application/json`

```json
{
  "isSuperAdmin": true,
  "features": [
    "string"
  ],
  "organizations": null
}
```

**400** – Invalid role id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/roles/acl?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/auth/roles/acl`

Update role ACL

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

Requires features: auth.acl.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.acl.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Role ACL updated

Content-Type: `application/json`

```json
{
  "ok": true,
  "sanitized": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Authentication & Accounts

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| redirect | query | any | Optional. Absolute or relative URL to redirect after refresh |

### Responses

**200** – Success response

Content-Type: `application/json`

**302** – Redirect to target location when session is valid

Content-Type: `text/html`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Authentication & Accounts

### Request Body

Content-Type: `application/json`

```json
{
  "refreshToken": "string"
}
```

### Responses

**200** – New access token issued

Content-Type: `application/json`

```json
{
  "ok": true,
  "accessToken": "string",
  "expiresIn": 1
}
```

**400** – Missing refresh token

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Invalid or expired token

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**429** – Too many refresh attempts

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/session/refresh" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"refreshToken\": \"string\"
}"
```

## GET `/auth/sidebar/preferences`

Get sidebar preferences

Returns personal sidebar customization and any role-level preferences the user can manage.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Responses

**200** – Current sidebar configuration

Content-Type: `application/json`

```json
{
  "locale": "string",
  "settings": {
    "version": 1,
    "groupOrder": [
      "string"
    ],
    "groupLabels": {
      "key": "string"
    },
    "itemLabels": {
      "key": "string"
    },
    "hiddenItems": [
      "string"
    ]
  },
  "canApplyToRoles": true,
  "roles": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "hasPreference": true
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/sidebar/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/auth/sidebar/preferences`

Update sidebar preferences

Updates personal sidebar configuration and, optionally, applies the same settings to selected roles.

**Tags:** Authentication & Accounts

**Requires authentication.**

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Preferences saved

Content-Type: `application/json`

```json
{
  "locale": "string",
  "settings": {
    "version": 1,
    "groupOrder": [
      "string"
    ],
    "groupLabels": {
      "key": "string"
    },
    "itemLabels": {
      "key": "string"
    },
    "hiddenItems": [
      "string"
    ]
  },
  "canApplyToRoles": true,
  "roles": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "hasPreference": true
    }
  ],
  "appliedRoles": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "clearedRoles": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Missing features for role-wide updates

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/auth/sidebar/preferences" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## DELETE `/auth/users`

Delete user

Deletes a user by identifier. Undo support is provided via the command bus.

Requires features: auth.users.delete

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.users.delete

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. User identifier |

### Responses

**200** – User deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – User cannot be deleted

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/auth/users?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/auth/users`

List users

Returns users for the current tenant. Super administrators may scope the response via organization or role filters.

Requires features: auth.users.list

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.users.list

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| organizationId | query | any | Optional |
| roleIds | query | any | Optional |

### Responses

**200** – User collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "email": "user@example.com",
      "organizationId": null,
      "organizationName": null,
      "tenantId": null,
      "tenantName": null,
      "roles": [
        "string"
      ]
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/users?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/auth/users`

Create user

Creates a new confirmed user within the specified organization and optional roles.

Requires features: auth.users.create

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.users.create

### Request Body

Content-Type: `application/json`

```json
{
  "email": "user@example.com",
  "password": "string",
  "organizationId": "00000000-0000-4000-8000-000000000000"
}
```

### Responses

**201** – User created

Content-Type: `application/json`

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

**400** – Invalid payload or duplicate email

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/auth/users" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\",
  \"organizationId\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## PUT `/auth/users`

Update user

Updates profile fields, organization assignment, credentials, or role memberships.

Requires features: auth.users.edit

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.users.edit

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – User updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/auth/users" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## GET `/auth/users/acl`

Fetch user ACL

Returns custom ACL overrides for a user within the current tenant, if any.

Requires features: auth.acl.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.acl.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| userId | query | any | Required |

### Responses

**200** – User ACL entry

Content-Type: `application/json`

```json
{
  "hasCustomAcl": true,
  "isSuperAdmin": true,
  "features": [
    "string"
  ],
  "organizations": null
}
```

**400** – Invalid user id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/auth/users/acl?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/auth/users/acl`

Update user ACL

Configures per-user ACL overrides, including super admin access, feature list, and organization scope.

Requires features: auth.acl.manage

**Tags:** Authentication & Accounts

**Requires authentication.**

**Features:** auth.acl.manage

### Request Body

Content-Type: `application/json`

```json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "organizations": null
}
```

### Responses

**200** – User ACL updated

Content-Type: `application/json`

```json
{
  "ok": true,
  "sanitized": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/auth/users/acl" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\",
  \"organizations\": null
}"
```

## POST `/business_rules/execute`

Execute rules for given context

Manually executes applicable business rules for the specified entity type, event, and data. Supports dry-run mode to test rules without executing actions.

Requires features: business_rules.execute

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.execute

### Request Body

Content-Type: `application/json`

```json
{
  "entityType": "string",
  "dryRun": false
}
```

### Responses

**200** – Rules executed successfully

Content-Type: `application/json`

```json
{
  "allowed": true,
  "executedRules": [
    {
      "ruleId": "string",
      "ruleName": "string",
      "conditionResult": true,
      "executionTime": 1
    }
  ],
  "totalExecutionTime": 1
}
```

**400** – Invalid request payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Execution error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/business_rules/execute" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\",
  \"dryRun\": false
}"
```

## POST `/business_rules/execute/{ruleId}`

Execute a specific rule by its database UUID

Directly executes a specific business rule identified by its UUID, bypassing the normal entityType/eventType discovery mechanism. Useful for workflows and targeted rule execution.

Requires features: business_rules.execute

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.execute

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| ruleId | path | any | Required. The database UUID of the business rule to execute |

### Request Body

Content-Type: `application/json`

```json
{
  "dryRun": false
}
```

### Responses

**200** – Rule executed successfully

Content-Type: `application/json`

```json
{
  "success": true,
  "ruleId": "string",
  "ruleName": "string",
  "conditionResult": true,
  "actionsExecuted": null,
  "executionTime": 1
}
```

**400** – Invalid request payload or rule ID

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Rule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Execution error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/business_rules/execute/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"dryRun\": false
}"
```

## GET `/business_rules/logs`

List rule execution logs

Returns rule execution history for the current tenant and organization with filtering and pagination. Useful for audit trails and debugging.

Requires features: business_rules.view_logs

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view_logs

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| ruleId | query | any | Optional |
| entityId | query | any | Optional |
| entityType | query | any | Optional |
| executionResult | query | any | Optional |
| executedBy | query | any | Optional |
| executedAtFrom | query | any | Optional |
| executedAtTo | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |

### Responses

**200** – Rule execution logs collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "string",
      "ruleId": "string",
      "ruleName": "string",
      "ruleType": "string",
      "entityId": "00000000-0000-4000-8000-000000000000",
      "entityType": "string",
      "executionResult": "SUCCESS",
      "inputContext": null,
      "outputContext": null,
      "errorMessage": null,
      "executionTimeMs": 1,
      "executedAt": "string",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": null,
      "executedBy": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/logs?page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/business_rules/logs/{id}`

Get execution log detail

Returns detailed information about a specific rule execution, including full context and results.

Requires features: business_rules.view_logs

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view_logs

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Log entry details

Content-Type: `application/json`

```json
{
  "id": "string",
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "ruleId": "string",
    "ruleName": "string",
    "ruleType": "string",
    "entityType": "string"
  },
  "entityId": "00000000-0000-4000-8000-000000000000",
  "entityType": "string",
  "executionResult": "SUCCESS",
  "inputContext": null,
  "outputContext": null,
  "errorMessage": null,
  "executionTimeMs": 1,
  "executedAt": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": null,
  "executedBy": null
}
```

**400** – Invalid log id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Log entry not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/logs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/business_rules/rules`

Delete business rule

Soft deletes a business rule by identifier.

Requires features: business_rules.manage

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Business rule identifier |

### Responses

**200** – Business rule deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Business rule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/business_rules/rules?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/business_rules/rules`

List business rules

Returns business rules for the current tenant and organization with filtering and pagination.

Requires features: business_rules.view

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| ruleId | query | any | Optional |
| ruleType | query | any | Optional |
| entityType | query | any | Optional |
| eventType | query | any | Optional |
| enabled | query | any | Optional |
| ruleCategory | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |

### Responses

**200** – Business rules collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ruleId": "string",
      "ruleName": "string",
      "description": null,
      "ruleType": "GUARD",
      "ruleCategory": null,
      "entityType": "string",
      "eventType": null,
      "enabled": true,
      "priority": 1,
      "version": 1,
      "effectiveFrom": null,
      "effectiveTo": null,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/rules?page=1&pageSize=50&sortDir=desc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/business_rules/rules`

Create business rule

Creates a new business rule for the current tenant and organization.

Requires features: business_rules.manage

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage

### Request Body

Content-Type: `application/json`

```json
{
  "ruleId": "string",
  "ruleName": "string",
  "description": null,
  "ruleType": "GUARD",
  "ruleCategory": null,
  "entityType": "string",
  "eventType": null,
  "enabled": true,
  "priority": 100,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "tenantId": "string",
  "organizationId": "string",
  "createdBy": null,
  "successActions": null,
  "failureActions": null
}
```

### Responses

**201** – Business rule created

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/business_rules/rules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ruleId\": \"string\",
  \"ruleName\": \"string\",
  \"description\": null,
  \"ruleType\": \"GUARD\",
  \"ruleCategory\": null,
  \"entityType\": \"string\",
  \"eventType\": null,
  \"enabled\": true,
  \"priority\": 100,
  \"version\": 1,
  \"effectiveFrom\": null,
  \"effectiveTo\": null,
  \"tenantId\": \"string\",
  \"organizationId\": \"string\",
  \"createdBy\": null,
  \"successActions\": null,
  \"failureActions\": null
}"
```

## PUT `/business_rules/rules`

Update business rule

Updates an existing business rule.

Requires features: business_rules.manage

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage

### Request Body

Content-Type: `application/json`

```json
{
  "description": null,
  "ruleCategory": null,
  "eventType": null,
  "enabled": true,
  "priority": 100,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "createdBy": null,
  "successActions": null,
  "failureActions": null,
  "id": "string"
}
```

### Responses

**200** – Business rule updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Business rule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/business_rules/rules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"ruleCategory\": null,
  \"eventType\": null,
  \"enabled\": true,
  \"priority\": 100,
  \"version\": 1,
  \"effectiveFrom\": null,
  \"effectiveTo\": null,
  \"createdBy\": null,
  \"successActions\": null,
  \"failureActions\": null,
  \"id\": \"string\"
}"
```

## GET `/business_rules/rules/{id}`

Fetch business rule by ID

Returns complete details of a business rule including conditions and actions.

Requires features: business_rules.view

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Business rule detail

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "ruleId": "string",
  "ruleName": "string",
  "description": null,
  "ruleType": "GUARD",
  "ruleCategory": null,
  "entityType": "string",
  "eventType": null,
  "successActions": null,
  "failureActions": null,
  "enabled": true,
  "priority": 1,
  "version": 1,
  "effectiveFrom": null,
  "effectiveTo": null,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "createdBy": null,
  "updatedBy": null,
  "createdAt": "string",
  "updatedAt": "string"
}
```

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Business rule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/rules/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/business_rules/sets`

Delete rule set

Soft deletes a rule set by identifier.

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Rule set identifier |

### Responses

**200** – Rule set deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Rule set not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/business_rules/sets?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/business_rules/sets`

List rule sets

Returns rule sets for the current tenant and organization with filtering and pagination.

Requires features: business_rules.view

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| setId | query | any | Optional |
| enabled | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |

### Responses

**200** – Rule sets collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "setId": "string",
      "setName": "string",
      "description": null,
      "enabled": true,
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "createdBy": null,
      "updatedBy": null,
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/sets?page=1&pageSize=50&sortDir=asc" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/business_rules/sets`

Create rule set

Creates a new rule set for organizing business rules.

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Request Body

Content-Type: `application/json`

```json
{
  "setId": "string",
  "setName": "string",
  "description": null,
  "enabled": true,
  "tenantId": "string",
  "organizationId": "string",
  "createdBy": null
}
```

### Responses

**201** – Rule set created

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/business_rules/sets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"setId\": \"string\",
  \"setName\": \"string\",
  \"description\": null,
  \"enabled\": true,
  \"tenantId\": \"string\",
  \"organizationId\": \"string\",
  \"createdBy\": null
}"
```

## PUT `/business_rules/sets`

Update rule set

Updates an existing rule set.

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Request Body

Content-Type: `application/json`

```json
{
  "description": null,
  "enabled": true,
  "createdBy": null,
  "id": "string"
}
```

### Responses

**200** – Rule set updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Rule set not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/business_rules/sets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"description\": null,
  \"enabled\": true,
  \"createdBy\": null,
  \"id\": \"string\"
}"
```

## GET `/business_rules/sets/{id}`

Get rule set detail

Returns detailed information about a specific rule set, including all member rules.

Requires features: business_rules.view

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Rule set details

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "setId": "string",
  "setName": "string",
  "description": null,
  "enabled": true,
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "createdBy": null,
  "updatedBy": null,
  "createdAt": "string",
  "updatedAt": "string",
  "members": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ruleId": "00000000-0000-4000-8000-000000000000",
      "ruleName": "string",
      "ruleType": "string",
      "sequence": 1,
      "enabled": true
    }
  ]
}
```

**400** – Invalid rule set id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Rule set not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/business_rules/sets/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/business_rules/sets/{id}/members`

Remove rule from set

Removes a business rule from a rule set (hard delete).

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |
| memberId | query | any | Required. Member identifier |

### Responses

**200** – Member removed

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Member not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/business_rules/sets/:id/members?memberId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/business_rules/sets/{id}/members`

Add rule to set

Adds a business rule to a rule set with specified sequence and enabled state.

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "ruleId": "00000000-0000-4000-8000-000000000000",
  "sequence": 0,
  "enabled": true
}
```

### Responses

**201** – Member added

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Rule set or rule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Rule already in set

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/business_rules/sets/:id/members" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"ruleId\": \"00000000-0000-4000-8000-000000000000\",
  \"sequence\": 0,
  \"enabled\": true
}"
```

## PUT `/business_rules/sets/{id}/members`

Update set member

Updates sequence or enabled state of a rule set member.

Requires features: business_rules.manage_sets

**Tags:** Business Rules

**Requires authentication.**

**Features:** business_rules.manage_sets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "memberId": "00000000-0000-4000-8000-000000000000"
}
```

### Responses

**200** – Member updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Member not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/business_rules/sets/:id/members" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"memberId\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## GET `/chain_relayers/admin/stream`

Subscribe to cross-tenant operation status events via SSE (platform admin only)

Long-lived SSE connection that receives chain_relayers.operation.* events across all tenants. Requires platform.chain_relayers.analytics feature.

Requires features: platform.chain_relayers.analytics

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** platform.chain_relayers.analytics

### Responses

**200** – Event stream (text/event-stream)

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/admin/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/alerts/config`

List all alert configurations for the tenant (returns defaults for unconfigured types)

Requires features: chain_relayers.manage

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Responses

**200** – Alert configurations list

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/alerts/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/chain_relayers/alerts/config`

Upsert an alert configuration for a specific alert type

Requires features: chain_relayers.manage

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Responses

**200** – Alert configuration upserted

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/chain_relayers/alerts/config" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/analytics/revenue`

Get revenue analytics with time series, summary totals, and provider comparison

Requires features: chain_relayers.view

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| from | query | any | Required |
| to | query | any | Required |
| groupBy | query | any | Optional |
| format | query | any | Optional |

### Responses

**200** – Revenue analytics data

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/analytics/revenue?from=string&to=string&groupBy=day" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/analytics/usage`

Get usage analytics aggregated by time period

Requires features: chain_relayers.view

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| from | query | any | Required |
| to | query | any | Required |
| groupBy | query | any | Optional |
| chain | query | any | Optional |
| mode | query | any | Optional |
| source | query | any | Optional |
| environment | query | any | Optional |
| format | query | any | Optional |

### Responses

**200** – Usage analytics data

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/analytics/usage?from=string&to=string&groupBy=day" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/construct-tx`

Construct unsigned Tron transaction(s) for wallet signing

Builds unsigned transaction(s) via TronWeb SDK using tenant credentials. Returns one TX for sponsored_broadcast and two TXs for token_pay or trx_fee_token_pay. Includes an inline cost estimate when available (null on estimation failure). The transaction(s) can then be signed by the connected wallet and submitted to /execute.

Requires features: chain_relayers.execute

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.execute

### Responses

**200** – Unsigned transaction(s) constructed

Content-Type: `application/json`

**422** – Invalid parameters

Content-Type: `application/json`

**429** – Rate limit exceeded

Content-Type: `application/json`

**500** – TronGrid unavailable or transaction construction failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/construct-tx" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/estimate`

Estimate cost for a gasless relay operation (dry-run)

Requires features: chain_relayers.estimate

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.estimate

### Responses

**200** – Cost estimate returned

Content-Type: `application/json`

**422** – Invalid payload or unsupported chain/mode

Content-Type: `application/json`

**502** – Provider estimation failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/estimate" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/execute`

Execute gasless relay operation (async or sync mode)

Requires features: chain_relayers.execute

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.execute

### Responses

**200** – Existing operation returned (idempotency) or sync result

Content-Type: `application/json`

**202** – Operation accepted for async processing

Content-Type: `application/json`

**400** – Pre-flight TX validation failed (malformed, unsigned, or expired)

Content-Type: `application/json`

**422** – Validation failure (INVALID_PAYLOAD), removed field (UNSUPPORTED_FIELD), or delegate energy below provider minimum (ENERGY_AMOUNT_BELOW_MINIMUM)

Content-Type: `application/json`

**502** – Workflow failed to start

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/execute" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/operations`

List relay operations with filters and pagination

Requires features: chain_relayers.view

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – Paginated list of operations

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/operations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/operations/{id}/retry`

Creates a new operation with the same parameters as the failed one and dispatches it to the workflow engine

Creates a new operation with the same parameters as the original failed or expired operation and dispatches it to the workflow engine.

Requires features: chain_relayers.manage

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Retry operation created and dispatched

Content-Type: `application/json`

**404** – Operation not found

Content-Type: `application/json`

**409** – Operation cannot be retried (not in failed/expired status)

Content-Type: `application/json`

**422** – No adapter available for chain/mode

Content-Type: `application/json`

**502** – Workflow failed to start for retried operation

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/operations/:id/retry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/operations/{id}/void`

Void a relay operation in any non-terminal status, releasing held funds and cancelling workflows

Requires features: chain_relayers.manage

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Operation voided successfully

Content-Type: `application/json`

**404** – Operation not found

Content-Type: `application/json`

**409** – Operation cannot be voided (already in terminal status)

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/operations/:id/void" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/operations/attention`

Get operations and delegations needing attention

Returns operations and delegations grouped by category that require operator attention: stuck operations, reconciliation-needed items, recent failures, and compensation-needed delegations.

Requires features: chain_relayers.view

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – Attention items grouped by category

Content-Type: `application/json`

**502** – Failed to fetch attention data

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/operations/attention" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/operations/stats`

Get aggregated operation statistics for the dashboard metrics bar

Requires features: chain_relayers.view

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – Aggregated operation statistics

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/operations/stats" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/chain_relayers/portal/construct-tx`

Construct unsigned Tron transaction(s) for wallet signing

Builds unsigned transaction(s) via TronWeb SDK using tenant credentials. Returns one TX for sponsored_broadcast and two TXs for token_pay or trx_fee_token_pay. Includes an inline cost estimate when available (null on estimation failure). The transaction(s) can then be signed by the connected wallet and submitted to /execute.

**Tags:** Portal Relay

### Responses

**200** – Unsigned transaction(s) constructed

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**422** – Invalid parameters

Content-Type: `application/json`

**500** – TronGrid unavailable or transaction construction failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/portal/construct-tx" \
  -H "Accept: application/json"
```

## POST `/chain_relayers/portal/dry-run`

Dry-run transaction simulation before signing

**Tags:** Chain Relayers Portal

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/portal/dry-run" \
  -H "Accept: application/json"
```

## POST `/chain_relayers/portal/estimate`

Estimate cost for a gasless relay operation from the customer portal

**Tags:** Customer Portal, ChainRelayers

### Responses

**200** – Cost estimate returned

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid payload or unsupported chain/mode

Content-Type: `application/json`

**429** – Rate limit exceeded

Content-Type: `application/json`

**502** – Provider estimation failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/portal/estimate" \
  -H "Accept: application/json"
```

## POST `/chain_relayers/portal/execute`

Execute a gasless relay operation from the customer portal

**Tags:** Customer Portal, ChainRelayers

### Responses

**200** – Existing operation returned (idempotency hit)

Content-Type: `application/json`

**202** – Operation accepted for async processing

Content-Type: `application/json`

**400** – Pre-flight TX validation failed (malformed, unsigned, or expired)

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Validation failure (Validation failed), removed field (UNSUPPORTED_FIELD), or delegate energy below provider minimum (ENERGY_AMOUNT_BELOW_MINIMUM)

Content-Type: `application/json`

**429** – Rate limit exceeded

Content-Type: `application/json`

**502** – Workflow failed to start

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/portal/execute" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/portal/operations`

List relay operations for the authenticated customer

**Tags:** Customer Portal, ChainRelayers

### Responses

**200** – Paginated list of relay operations

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/portal/operations" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/portal/operations/{id}`

Get a single relay operation by ID for the authenticated customer

**Tags:** Customer Portal, ChainRelayers

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Operation details

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**404** – Operation not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/portal/operations/:id" \
  -H "Accept: application/json"
```

## POST `/chain_relayers/portal/operations/{id}/cancel`

Cancel a relay operation from the customer portal (void non-terminal operations)

**Tags:** Customer Portal, ChainRelayers

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Operation cancelled successfully

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**404** – Operation not found or belongs to a different tenant

Content-Type: `application/json`

**409** – Operation already in a terminal state

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/chain_relayers/portal/operations/:id/cancel" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/portal/operations/stats`

Get aggregated relay operation statistics for the authenticated customer

**Tags:** Customer Portal, ChainRelayers

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| environment | query | any | Optional |

### Responses

**200** – Aggregated operation statistics

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/portal/operations/stats" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/portal/providers`

List available relay providers and their supported modes

**Tags:** Customer Portal, ChainRelayers

### Responses

**200** – List of providers with supported modes

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/portal/providers" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/portal/stream`

Subscribe to a single relay operation stream (portal)

**Tags:** Customer Portal, ChainRelayers

### Responses

**200** – Event stream (text/event-stream)

Content-Type: `application/json`

**400** – Invalid operationId query parameter

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Operation not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/portal/stream" \
  -H "Accept: application/json"
```

## GET `/chain_relayers/providers`

List all registered chain relayer providers and their supported modes

Requires features: chain_relayers.view

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – List of registered providers

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/providers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/providers/health`

Return health status for all registered energy providers from cache

Requires features: chain_relayers.view

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – Provider health data returned

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/providers/health" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/settings`

Get current platform settings with defaults

Requires features: chain_relayers.manage

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Responses

**200** – Current platform settings

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/chain_relayers/settings`

Update platform settings (partial update)

Requires features: chain_relayers.manage

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.manage

### Responses

**200** – Settings updated

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/chain_relayers/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/status/{id}`

Poll a single relay operation status

Requires features: chain_relayers.view

**Tags:** Chain Relayers

**Requires authentication.**

**Features:** chain_relayers.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Operation status returned

Content-Type: `application/json`

**404** – Operation not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/status/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/chain_relayers/stream`

Subscribe to one relay operation status stream

Long-lived SSE connection for one operation. Requires operationId query parameter.

Requires features: chain_relayers.view

**Tags:** ChainRelayers

**Requires authentication.**

**Features:** chain_relayers.view

### Responses

**200** – Event stream (text/event-stream)

Content-Type: `application/json`

**400** – Invalid operationId query parameter

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/chain_relayers/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/configs/cache`

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

**Tags:** Configs

**Requires authentication.**

**Features:** configs.cache.view

### Responses

**200** – Cache statistics

Content-Type: `application/json`

```json
{
  "total": 1,
  "segments": {
    "key": 1
  }
}
```

**500** – Failed to resolve cache stats

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**503** – Cache service unavailable

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/configs/cache`

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

**Tags:** Configs

**Requires authentication.**

**Features:** configs.cache.manage

### Request Body

Content-Type: `application/json`

```json
{
  "action": "purgeAll"
}
```

### Responses

**200** – Cache segment cleared successfully

Content-Type: `application/json`

```json
{
  "action": "purgeSegment",
  "segment": "string",
  "deleted": 1,
  "stats": {
    "total": 1,
    "segments": {
      "key": 1
    }
  }
}
```

**400** – Invalid request - missing segment identifier for purgeSegment action

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to purge cache

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**503** – Cache service unavailable

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/configs/cache" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"action\": \"purgeAll\"
}"
```

## GET `/configs/system-status`

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

**Tags:** Configs

**Requires authentication.**

**Features:** configs.system_status.view

### Responses

**200** – System status snapshot

Content-Type: `application/json`

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

**500** – Failed to load system status

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/configs/system-status`

Clear system cache

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

Requires features: configs.manage

**Tags:** Configs

**Requires authentication.**

**Features:** configs.manage

### Responses

**200** – Cache cleared successfully

Content-Type: `application/json`

```json
{
  "cleared": true
}
```

**500** – Failed to purge cache

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**503** – Cache service unavailable

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/configs/system-status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/configs/upgrade-actions`

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

**Tags:** Configs

**Requires authentication.**

**Features:** configs.manage

### Responses

**200** – List of pending upgrade actions

Content-Type: `application/json`

```json
{
  "version": "string",
  "actions": [
    {
      "id": "string",
      "version": "string",
      "message": "string",
      "ctaLabel": "string",
      "successMessage": "string",
      "loadingLabel": "string"
    }
  ]
}
```

**400** – Missing organization or tenant context

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to load upgrade actions

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/configs/upgrade-actions`

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

**Tags:** Configs

**Requires authentication.**

**Features:** configs.manage

### Request Body

Content-Type: `application/json`

```json
{
  "actionId": "string"
}
```

### Responses

**200** – Upgrade action executed successfully

Content-Type: `application/json`

```json
{
  "status": "string",
  "message": "string",
  "version": "string"
}
```

**400** – Invalid request body or missing context

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to execute upgrade action

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/configs/upgrade-actions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"actionId\": \"string\"
}"
```

## GET `/customer_accounts/admin/roles`

List customer roles (admin)

Returns all customer roles for the tenant.

**Tags:** Customer Accounts Admin

### Responses

**200** – Role list

Content-Type: `application/json`

```json
{
  "ok": true,
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "slug": "string",
      "description": null,
      "isDefault": true,
      "isSystem": true,
      "customerAssignable": true,
      "createdAt": "string"
    }
  ],
  "total": 1,
  "totalPages": 1,
  "page": 1
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Accounts Admin

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Role created

Content-Type: `application/json`

```json
{
  "ok": true,
  "role": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "slug": "string",
    "description": null,
    "isDefault": true,
    "isSystem": true,
    "customerAssignable": true,
    "createdAt": "string"
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**409** – Slug already exists

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_accounts/admin/roles" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"slug\": \"string\"
}"
```

## DELETE `/customer_accounts/admin/roles/{id}`

Delete customer role (admin)

Soft deletes a customer role and its ACL. System roles and roles with assigned users cannot be deleted.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Role deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – System role or has assigned users

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
```

## GET `/customer_accounts/admin/roles/{id}`

Get customer role detail (admin)

Returns full customer role details including ACL features.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Role detail with ACL

Content-Type: `application/json`

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

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Role updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed or system role restriction

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/customer_accounts/admin/roles/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## 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.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "features": [
    "string"
  ]
}
```

### Responses

**200** – ACL updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Role not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| status | query | any | Optional |
| customerEntityId | query | any | Optional |
| roleId | query | any | Optional |
| search | query | any | Optional |

### Responses

**200** – Paginated user list

Content-Type: `application/json`

```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",
      "roles": [
        {
          "id": "00000000-0000-4000-8000-000000000000",
          "name": "string",
          "slug": "string"
        }
      ]
    }
  ],
  "total": 1,
  "totalPages": 1,
  "page": 1
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Accounts Admin

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – User created

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string"
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**409** – Email already exists

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Accounts Admin

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Invitation created

Content-Type: `application/json`

```json
{
  "ok": true,
  "invitation": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "expiresAt": "string"
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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\"
  ]
}"
```

## DELETE `/customer_accounts/admin/users/{id}`

Delete customer user (admin)

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

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – User deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
```

## GET `/customer_accounts/admin/users/{id}`

Get customer user detail (admin)

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

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – User detail

Content-Type: `application/json`

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

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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, and roles. Role assignment bypasses customer_assignable check.

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – User updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed or role not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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
}"
```

## POST `/customer_accounts/admin/users/{id}/reset-password`

Reset customer user password (admin)

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

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "newPassword": "string"
}
```

### Responses

**200** – Password reset

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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}/verify-email`

Verify customer user email (admin)

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

**Tags:** Customer Accounts Admin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Email verified

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_accounts/admin/users/00000000-0000-4000-8000-000000000000/verify-email" \
  -H "Accept: application/json"
```

## POST `/customer_accounts/email/verify`

Verify customer email address

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

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

```json
{
  "token": "string"
}
```

### Responses

**200** – Email verified

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid or expired token

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Invitation accepted and user created

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
```

**400** – Invalid or expired invitation

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Login successful

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Invalid credentials

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**423** – Account locked

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**429** – Too many login attempts

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Request accepted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**429** – Too many requests

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

```json
{
  "token": "string"
}
```

### Responses

**200** – Login successful

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  },
  "resolvedFeatures": [
    "string"
  ]
}
```

**400** – Invalid or expired token

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Account not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Password reset successful

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid or expired token

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Request accepted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**429** – Too many requests

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_accounts/password/reset-request" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\"
}"
```

## 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 and organization.

**Tags:** Customer Portal

### Responses

**200** – Event stream (text/event-stream)

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Request Body

Content-Type: `application/json`

```json
{
  "features": [
    "string"
  ]
}
```

### Responses

**200** – Feature check result

Content-Type: `application/json`

```json
{
  "ok": true,
  "granted": [
    "string"
  ]
}
```

**400** – Invalid request

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – Logged out

Content-Type: `application/json`

```json
{
  "ok": true
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_accounts/portal/logout" \
  -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.

**Tags:** Customer Portal

### Responses

**200** – Notification list

Content-Type: `application/json`

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

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Notification dismissed

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Notification not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Notification marked as read

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Notification not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – All notifications marked as read

Content-Type: `application/json`

```json
{
  "ok": true,
  "count": 1
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – Unread count

Content-Type: `application/json`

```json
{
  "ok": true,
  "unreadCount": 1
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Password changed

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Current password incorrect or validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – Profile data

Content-Type: `application/json`

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

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/customer_accounts/portal/profile" \
  -H "Accept: application/json"
```

## PUT `/customer_accounts/portal/profile`

Update customer profile

Updates the authenticated customer user profile.

**Tags:** Customer Portal

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Profile updated

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "displayName": "string"
  }
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – Session list

Content-Type: `application/json`

```json
{
  "ok": true,
  "sessions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "ipAddress": null,
      "userAgent": null,
      "lastUsedAt": null,
      "createdAt": "string",
      "expiresAt": "string",
      "isCurrent": true
    }
  ]
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Responses

**200** – Token refreshed

Content-Type: `application/json`

```json
{
  "ok": true,
  "resolvedFeatures": [
    "string"
  ]
}
```

**401** – Invalid session

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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).

**Tags:** Customer Portal

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Session revoked

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Cannot revoke current session

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – Session not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/customer_accounts/portal/sessions/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json"
```

## GET `/customer_accounts/portal/users`

List company portal users

Lists all portal users associated with the same company.

**Tags:** Customer Portal

### Responses

**200** – User list

Content-Type: `application/json`

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

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Invitation created

Content-Type: `application/json`

```json
{
  "ok": true,
  "invitation": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "string",
    "expiresAt": "string"
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions or non-assignable role

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – User deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Cannot delete self

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/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.

**Tags:** Customer Portal

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Roles updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**401** – Not authenticated

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**403** – Insufficient permissions

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**404** – User not found

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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\"
  ]
}"
```

## POST `/customer_accounts/signup`

Register a new customer account

Creates a new customer user account and sends an email verification token.

**Tags:** Customer Authentication

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Account created successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "user": {
    "id": "00000000-0000-4000-8000-000000000000",
    "email": "user@example.com",
    "displayName": "string",
    "emailVerified": true
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**409** – Email already registered

Content-Type: `application/json`

```json
{
  "ok": false,
  "error": "string"
}
```

**429** – Too many signup attempts

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_accounts/signup" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"email\": \"user@example.com\",
  \"password\": \"string\",
  \"displayName\": \"string\"
}"
```

## DELETE `/customer_api_keys/portal/keys`

Revoke a customer API key

Soft-deletes the API key and its link record. Immediate invalidation.

**Tags:** Customer Portal, API Keys

### Responses

**200** – Key revoked

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**404** – Key not found or not owned by customer

Content-Type: `application/json`

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/customer_api_keys/portal/keys" \
  -H "Accept: application/json"
```

## GET `/customer_api_keys/portal/keys`

List customer API keys

Returns paginated list of API keys owned by the authenticated portal customer.

**Tags:** Customer Portal, API Keys

### Responses

**200** – API key list

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/customer_api_keys/portal/keys" \
  -H "Accept: application/json"
```

## POST `/customer_api_keys/portal/keys`

Create a customer API key

Creates a new API key with the customer role. The secret is returned once and cannot be retrieved later.

**Tags:** Customer Portal, API Keys

### Responses

**201** – API key created with secret

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**422** – Validation failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/customer_api_keys/portal/keys" \
  -H "Accept: application/json"
```

## GET `/dashboards/layout`

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

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.view

### Responses

**200** – Current dashboard layout and available widgets.

Content-Type: `application/json`

```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

```bash
curl -X GET "https://apiv2.tronergy.io/dashboards/layout" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/dashboards/layout`

Persist dashboard layout changes

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

Requires features: dashboards.configure

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.configure

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Layout updated successfully.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid layout payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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}`

Update a dashboard layout item

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

Requires features: dashboards.configure

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| itemId | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Layout item updated.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Invalid payload or missing item id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Item not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PATCH "https://apiv2.tronergy.io/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`

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

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.admin.assign-widgets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| roleId | query | any | Required |
| tenantId | query | any | Optional |
| organizationId | query | any | Optional |

### Responses

**200** – Current widget configuration for the role.

Content-Type: `application/json`

```json
{
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
```

**400** – Missing role identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/dashboards/roles/widgets?roleId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/dashboards/roles/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

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.admin.assign-widgets

### Request Body

Content-Type: `application/json`

```json
{
  "roleId": "00000000-0000-4000-8000-000000000000",
  "tenantId": null,
  "organizationId": null,
  "widgetIds": [
    "string"
  ]
}
```

### Responses

**200** – Widgets updated successfully.

Content-Type: `application/json`

```json
{
  "ok": true,
  "widgetIds": [
    "string"
  ]
}
```

**400** – Invalid payload or unknown widgets

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/dashboards/roles/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"roleId\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": null,
  \"organizationId\": null,
  \"widgetIds\": [
    \"string\"
  ]
}"
```

## GET `/dashboards/users/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

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.admin.assign-widgets

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| userId | query | any | Required |
| tenantId | query | any | Optional |
| organizationId | query | any | Optional |

### Responses

**200** – Widget settings for the user.

Content-Type: `application/json`

```json
{
  "mode": "inherit",
  "widgetIds": [
    "string"
  ],
  "hasCustom": true,
  "effectiveWidgetIds": [
    "string"
  ],
  "scope": {
    "tenantId": null,
    "organizationId": null
  }
}
```

**400** – Missing user identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/dashboards/users/widgets?userId=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/dashboards/users/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

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.admin.assign-widgets

### Request Body

Content-Type: `application/json`

```json
{
  "userId": "00000000-0000-4000-8000-000000000000",
  "tenantId": null,
  "organizationId": null,
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}
```

### Responses

**200** – Overrides saved.

Content-Type: `application/json`

```json
{
  "ok": true,
  "mode": "inherit",
  "widgetIds": [
    "string"
  ]
}
```

**400** – Invalid payload or unknown widgets

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/dashboards/users/widgets" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"userId\": \"00000000-0000-4000-8000-000000000000\",
  \"tenantId\": null,
  \"organizationId\": null,
  \"mode\": \"inherit\",
  \"widgetIds\": [
    \"string\"
  ]
}"
```

## GET `/dashboards/widgets/catalog`

List available dashboard widgets

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

Requires features: dashboards.admin.assign-widgets

**Tags:** Dashboards

**Requires authentication.**

**Features:** dashboards.admin.assign-widgets

### Responses

**200** – Widgets available for assignment.

Content-Type: `application/json`

```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

```bash
curl -X GET "https://apiv2.tronergy.io/dashboards/widgets/catalog" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/dashboards/widgets/data`

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

**Tags:** Dashboards

**Requires authentication.**

**Features:** analytics.view

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Aggregated data for the widget.

Content-Type: `application/json`

```json
{
  "value": null,
  "data": [
    {
      "value": null
    }
  ],
  "metadata": {
    "fetchedAt": "string",
    "recordCount": 1
  }
}
```

**400** – Invalid request payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Internal server error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/dashboards/widgets/data" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\",
  \"metric\": {
    \"field\": \"string\",
    \"aggregate\": \"count\"
  }
}"
```

## GET `/data_sync/mappings`

List or create field mappings

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/mappings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/mappings`

List or create field mappings

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/mappings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/data_sync/mappings/{id}`

Get, update, or delete a field mapping

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**204** – Success

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/data_sync/mappings/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/mappings/{id}`

Get, update, or delete a field mapping

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/mappings/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/data_sync/mappings/{id}`

Get, update, or delete a field mapping

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/data_sync/mappings/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/options`

List data sync integration options

Requires features: data_sync.view

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.view

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/options" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/run`

Start a data sync run

Requires features: data_sync.run

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.run

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/run" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/runs`

List sync runs

Requires features: data_sync.view

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.view

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/runs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/runs/{id}`

Get sync run detail

Requires features: data_sync.view

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/runs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/runs/{id}/cancel`

Cancel a running sync

Requires features: data_sync.run

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.run

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/runs/:id/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/runs/{id}/retry`

Retry a failed sync run

Requires features: data_sync.run

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.run

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/runs/:id/retry" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/schedules`

List or create sync schedules

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/schedules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/schedules`

List or create sync schedules

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/schedules" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/data_sync/schedules/{id}`

Manage a sync schedule

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**204** – Success

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/data_sync/schedules/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/data_sync/schedules/{id}`

Manage a sync schedule

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/data_sync/schedules/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/data_sync/schedules/{id}`

Manage a sync schedule

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/data_sync/schedules/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/data_sync/validate`

Validate sync connection

Requires features: data_sync.configure

**Tags:** Data Sync

**Requires authentication.**

**Features:** data_sync.configure

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/data_sync/validate" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/dictionaries`

List dictionaries

Returns dictionaries accessible to the current organization, optionally including inactive records.

Requires features: dictionaries.view

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| includeInactive | query | any | Optional |

### Responses

**200** – Dictionary collection.

Content-Type: `application/json`

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

**500** – Failed to load dictionaries

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/dictionaries`

Create dictionary

Registers a dictionary scoped to the current organization.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Dictionary created.

Content-Type: `application/json`

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

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Dictionary key already exists

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to create dictionary

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/dictionaries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"key\": \"string\",
  \"name\": \"string\"
}"
```

## DELETE `/dictionaries/{dictionaryId}`

Delete dictionary

Soft deletes the dictionary unless it is the protected currency dictionary.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |

### Responses

**200** – Dictionary archived.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Protected dictionary cannot be deleted

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to delete dictionary

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/dictionaries/{dictionaryId}`

Get dictionary

Returns details for the specified dictionary, including inheritance flags.

Requires features: dictionaries.view

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |

### Responses

**200** – Dictionary details.

Content-Type: `application/json`

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

**400** – Invalid parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to load dictionary

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PATCH `/dictionaries/{dictionaryId}`

Update dictionary

Updates mutable attributes of the dictionary. Currency dictionaries are protected from modification.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Dictionary updated.

Content-Type: `application/json`

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

**400** – Validation failed or protected dictionary

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Dictionary key already exists

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to update dictionary

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PATCH "https://apiv2.tronergy.io/dictionaries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## GET `/dictionaries/{dictionaryId}/entries`

List dictionary entries

Returns entries for the specified dictionary ordered alphabetically.

Requires features: dictionaries.view

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |

### Responses

**200** – Dictionary entries.

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "value": "string",
      "label": "string",
      "color": null,
      "icon": null,
      "createdAt": "string",
      "updatedAt": null
    }
  ]
}
```

**400** – Invalid parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to load dictionary entries

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/dictionaries/00000000-0000-4000-8000-000000000000/entries" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/dictionaries/{dictionaryId}/entries`

Create dictionary entry

Creates a new entry in the specified dictionary.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Dictionary entry created.

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "createdAt": "string",
  "updatedAt": null
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to create dictionary entry

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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
}"
```

## DELETE `/dictionaries/{dictionaryId}/entries/{entryId}`

Delete dictionary entry

Deletes the specified dictionary entry via the command bus.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |
| entryId | path | any | Required |

### Responses

**200** – Entry deleted.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary or entry not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to delete entry

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/dictionaries/00000000-0000-4000-8000-000000000000/entries/00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PATCH `/dictionaries/{dictionaryId}/entries/{entryId}`

Update dictionary entry

Updates the specified dictionary entry using the command bus pipeline.

Requires features: dictionaries.manage

**Tags:** Dictionaries

**Requires authentication.**

**Features:** dictionaries.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| dictionaryId | path | any | Required |
| entryId | path | any | Required |

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Dictionary entry updated.

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "value": "string",
  "label": "string",
  "color": null,
  "icon": null,
  "createdAt": "string",
  "updatedAt": null
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Dictionary or entry not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Failed to update entry

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PATCH "https://apiv2.tronergy.io/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
}"
```

## GET `/directory/organization-switcher`

Load organization switcher menu

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

**Tags:** Directory

**Requires authentication.**

### Responses

**200** – Organization switcher payload.

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "depth": 1,
      "selectable": true,
      "children": []
    }
  ],
  "selectedId": null,
  "canManage": true,
  "tenantId": null,
  "tenants": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true
    }
  ],
  "isSuperAdmin": true
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/directory/organization-switcher" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/directory/organizations`

Delete organization

Soft deletes an organization identified by id.

Requires features: directory.organizations.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.organizations.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Organization deleted.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## GET `/directory/organizations`

List organizations

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

Requires features: directory.organizations.view

**Tags:** Directory

**Requires authentication.**

**Features:** directory.organizations.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| view | query | any | Optional |
| ids | query | any | Optional |
| tenantId | query | any | Optional |
| includeInactive | query | any | Optional |
| status | query | any | Optional |

### Responses

**200** – Organization data for the requested view.

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "parentId": null,
      "parentName": null,
      "tenantId": null,
      "tenantName": null,
      "rootId": null,
      "treePath": null
    }
  ]
}
```

**400** – Invalid query or tenant scope

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/directory/organizations?page=1&pageSize=50&view=options" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/directory/organizations`

Create organization

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

Requires features: directory.organizations.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.organizations.manage

### Request Body

Content-Type: `application/json`

```json
{
  "name": "string",
  "slug": null,
  "parentId": null
}
```

### Responses

**201** – Organization created.

Content-Type: `application/json`

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

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\",
  \"slug\": null,
  \"parentId\": null
}"
```

## PUT `/directory/organizations`

Update organization

Updates organization details and hierarchy assignments.

Requires features: directory.organizations.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.organizations.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Organization updated.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/directory/organizations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\",
  \"slug\": null,
  \"parentId\": null
}"
```

## GET `/directory/organizations/lookup`

Public organization lookup by slug

**Tags:** Directory (Tenants & Organizations)

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/directory/organizations/lookup" \
  -H "Accept: application/json"
```

## DELETE `/directory/tenants`

Delete tenant

Soft deletes the tenant identified by id.

Requires features: directory.tenants.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.tenants.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Tenant removed.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## GET `/directory/tenants`

List tenants

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

Requires features: directory.tenants.view

**Tags:** Directory

**Requires authentication.**

**Features:** directory.tenants.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |
| isActive | query | any | Optional |

### Responses

**200** – Paged list of tenants.

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "name": "string",
      "isActive": true,
      "createdAt": null,
      "updatedAt": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/directory/tenants?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/directory/tenants`

Create tenant

Creates a new tenant and returns its identifier.

Requires features: directory.tenants.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.tenants.manage

### Request Body

Content-Type: `application/json`

```json
{
  "name": "string"
}
```

### Responses

**201** – Tenant created.

Content-Type: `application/json`

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

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"name\": \"string\"
}"
```

## PUT `/directory/tenants`

Update tenant

Updates tenant properties such as name or activation state.

Requires features: directory.tenants.manage

**Tags:** Directory

**Requires authentication.**

**Features:** directory.tenants.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Tenant updated.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/directory/tenants" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## GET `/directory/tenants/lookup`

Public tenant lookup

**Tags:** Directory (Tenants & Organizations)

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/directory/tenants/lookup" \
  -H "Accept: application/json"
```

## DELETE `/entities/definitions`

Soft delete custom field definition

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Definition deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity id or key

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Definition not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
```

## GET `/entities/definitions`

List active custom field definitions

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

**Tags:** Entities

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Optional |
| entityIds | query | any | Optional |
| fieldset | query | any | Optional |

### Responses

**200** – Definition list

Content-Type: `application/json`

```json
{
  "items": [
    {
      "key": "string",
      "kind": "string",
      "label": "string",
      "entityId": "string"
    }
  ]
}
```

**400** – Missing entity id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/entities/definitions`

Upsert custom field definition

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Definition saved

Content-Type: `application/json`

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "key": "string",
    "kind": "string",
    "configJson": {}
  }
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/entities/definitions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\",
  \"kind\": \"text\"
}"
```

## POST `/entities/definitions.batch`

Save multiple custom field definitions

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Definitions saved

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Unexpected failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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`

Get management snapshot

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Required |

### Responses

**200** – Scoped definitions and deleted keys

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "key": "string",
      "kind": "string",
      "configJson": null,
      "organizationId": null,
      "tenantId": null
    }
  ],
  "deletedKeys": [
    "string"
  ]
}
```

**400** – Missing entity id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/definitions.manage?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/entities/definitions.restore`

Restore definition

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Definition restored

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity id or key

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Definition not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/entities/definitions.restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"key\": \"string\"
}"
```

## GET `/entities/encryption`

Fetch encryption map

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Required |

### Responses

**200** – Map

Content-Type: `application/json`

```json
{
  "entityId": "string",
  "fields": [
    {
      "field": "string",
      "hashField": null
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/encryption?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/entities/encryption`

Upsert encryption map

Creates or updates the encryption map for the current tenant/organization scope.

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Saved

Content-Type: `application/json`

```json
{
  "ok": true
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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
    }
  ]
}"
```

## DELETE `/entities/entities`

Soft delete custom entity

Marks the specified custom entity inactive within the current scope.

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

```json
{
  "entityId": "string"
}
```

### Responses

**200** – Entity deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Entity not found in scope

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\"
}"
```

## GET `/entities/entities`

List available entities

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

**Tags:** Entities

**Requires authentication.**

### Responses

**200** – List of entities

Content-Type: `application/json`

```json
{
  "items": [
    {
      "entityId": "string",
      "source": "code",
      "label": "string",
      "count": 1
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/entities/entities`

Upsert custom entity

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

Requires features: entities.definitions.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Entity saved

Content-Type: `application/json`

```json
{
  "ok": true,
  "item": {
    "id": "00000000-0000-4000-8000-000000000000",
    "entityId": "string",
    "label": "string"
  }
}
```

**400** – Validation error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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/records`

Delete record

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

Requires features: entities.records.manage

**Tags:** Entities

**Requires authentication.**

**Features:** entities.records.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Record deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity id or record id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Record not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Unexpected failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\"
}"
```

## GET `/entities/records`

List records

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

Requires features: entities.records.view

**Tags:** Entities

**Requires authentication.**

**Features:** entities.records.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Required |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |
| withDeleted | query | any | Optional |
| format | query | any | Optional |
| exportScope | query | any | Optional |
| export_scope | query | any | Optional |
| all | query | any | Optional |
| full | query | any | Optional |

### Responses

**200** – Paginated records

Content-Type: `application/json`

```json
{
  "items": [
    {}
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

**400** – Missing entity id

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Unexpected failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/records?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/entities/records`

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

**Tags:** Entities

**Requires authentication.**

**Features:** entities.records.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Record created

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Unexpected failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"values\": {}
}"
```

## PUT `/entities/records`

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

**Tags:** Entities

**Requires authentication.**

**Features:** entities.records.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Record updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Validation failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Unexpected failure

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/entities/records" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityId\": \"string\",
  \"recordId\": \"string\",
  \"values\": {}
}"
```

## GET `/entities/relations/options`

List relation options

Returns up to 50 option entries for populating relation dropdowns, automatically resolving label fields when omitted.

Requires features: entities.definitions.view

**Tags:** Entities

**Requires authentication.**

**Features:** entities.definitions.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityId | query | any | Required |
| labelField | query | any | Optional |
| q | query | any | Optional |

### Responses

**200** – Option list

Content-Type: `application/json`

```json
{
  "items": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/relations/options?entityId=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/entities/sidebar-entities`

Get sidebar entities

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

**Tags:** Entities

**Requires authentication.**

### Responses

**200** – Sidebar entities for navigation

Content-Type: `application/json`

```json
{
  "items": [
    {
      "entityId": "string",
      "label": "string",
      "href": "string"
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/entities/sidebar-entities" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/events/stream`

GET /events/stream

**Tags:** Events

**Requires authentication.**

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/events/stream" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/check/boolean`

Check if feature is enabled

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

**Tags:** Feature Toggles

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| identifier | query | any | Required. Feature toggle identifier |

### Responses

**200** – Feature status

Content-Type: `application/json`

```json
{
  "enabled": true,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
```

**400** – Bad Request

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Tenant not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/check/boolean?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/check/json`

Get json config

Gets the json configuration for a feature toggle.

**Tags:** Feature Toggles

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| identifier | query | any | Required. Feature toggle identifier |

### Responses

**200** – Json config

Content-Type: `application/json`

```json
{
  "valueType": "json",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
```

**400** – Bad Request

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Tenant not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/check/json?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/check/number`

Get number config

Gets the number configuration for a feature toggle.

**Tags:** Feature Toggles

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| identifier | query | any | Required. Feature toggle identifier |

### Responses

**200** – Number config

Content-Type: `application/json`

```json
{
  "valueType": "number",
  "value": 1,
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
```

**400** – Bad Request

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Tenant not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/check/number?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/check/string`

Get string config

Gets the string configuration for a feature toggle.

**Tags:** Feature Toggles

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| identifier | query | any | Required. Feature toggle identifier |

### Responses

**200** – String config

Content-Type: `application/json`

```json
{
  "valueType": "string",
  "value": "string",
  "source": "override",
  "toggleId": "string",
  "identifier": "string",
  "tenantId": "string"
}
```

**400** – Bad Request

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Tenant not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/check/string?identifier=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/feature_toggles/global`

Delete global feature toggle

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

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Feature toggle identifier |

### Responses

**200** – Feature toggle deleted

Content-Type: `application/json`

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

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - superadmin role required

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Feature toggle not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/feature_toggles/global?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/global`

List global feature toggles

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

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional. Page number for pagination |
| pageSize | query | any | Optional. Number of items per page (max 200) |
| search | query | any | Optional. Case-insensitive search across identifier, name, description, and category |
| type | query | any | Optional. Filter by toggle type (boolean, string, number, json) |
| category | query | any | Optional. Filter by category (case-insensitive partial match) |
| name | query | any | Optional. Filter by name (case-insensitive partial match) |
| identifier | query | any | Optional. Filter by identifier (case-insensitive partial match) |
| sortField | query | any | Optional. Field to sort by |
| sortDir | query | any | Optional. Sort direction (ascending or descending) |

### Responses

**200** – Feature toggles collection

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "identifier": "string",
      "name": "string",
      "description": null,
      "category": null,
      "type": "boolean",
      "defaultValue": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - superadmin role required

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/global?page=1&pageSize=50" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/feature_toggles/global`

Create global feature toggle

Creates a new global feature toggle. Requires superadmin role.

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Feature toggle created

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - superadmin role required

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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`

Update global feature toggle

Updates an existing global feature toggle. Requires superadmin role.

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Feature toggle updated

Content-Type: `application/json`

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

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Forbidden - superadmin role required

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Feature toggle not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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
}"
```

## GET `/feature_toggles/global/{id}`

Fetch feature toggle by ID

Returns complete details of a feature toggle.

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Feature toggle detail

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "identifier": "string",
  "name": "string",
  "description": null,
  "category": null,
  "type": "boolean",
  "defaultValue": null
}
```

**400** – Invalid identifier

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Feature toggle not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/global/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/global/{id}/override`

Fetch feature toggle override

Returns feature toggle override.

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Feature toggle overrides

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "tenantName": "string",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "toggleType": "boolean"
}
```

**400** – Invalid request

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Feature toggle not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/global/:id/override" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/feature_toggles/overrides`

List overrides

Returns list of feature toggle overrides.

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| category | query | any | Optional |
| name | query | any | Optional |
| identifier | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |

### Responses

**200** – List of overrides

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "toggleId": "00000000-0000-4000-8000-000000000000",
      "overrideState": "enabled",
      "identifier": "string",
      "name": "string",
      "category": null,
      "defaultState": true,
      "tenantName": null
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1,
  "isSuperAdmin": true
}
```

**400** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/feature_toggles/overrides?page=1&pageSize=25" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/feature_toggles/overrides`

Change override state

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

Requires roles: superadmin

**Tags:** Feature Toggles

**Requires authentication.**

**Roles:** superadmin

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Override updated

Content-Type: `application/json`

```json
{
  "ok": true,
  "overrideToggleId": null
}
```

**400** – Validation failed

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Internal server error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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
}"
```

## GET `/gas_tank/accounts`

List gas tank accounts with filters, pagination, and optional balance enrichment

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Responses

**200** – Paginated list of gas tank accounts (include=balance adds live ledger balances)

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/accounts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/gas_tank/accounts`

Create a new gas tank account

Requires features: gas_tank.manage

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.manage

### Responses

**201** – Gas tank account created

Content-Type: `application/json`

**400** – Unsupported chain

Content-Type: `application/json`

**409** – Account already exists for this chain and environment

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/gas_tank/accounts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/accounts/{id}`

Get a gas tank account with its current ledger balance

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Account with balance returned

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/accounts/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/gas_tank/accounts/{id}`

Update gas tank account status

Requires features: gas_tank.manage

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Account status updated

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**422** – Invalid payload or invalid status transition

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/gas_tank/accounts/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/gas_tank/accounts/{id}/adjust`

Apply a manual credit or debit to a gas tank account

Requires features: gas_tank.manage

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Adjustment applied successfully

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**422** – Invalid payload, account not active, or insufficient balance for debit

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/gas_tank/accounts/:id/adjust" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/accounts/{id}/alerts`

Get alert configuration for a gas tank account (returns defaults if not configured)

Requires features: gas_tank.manage

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Alert configuration

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/accounts/:id/alerts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/gas_tank/accounts/{id}/alerts`

Upsert alert configuration for a gas tank account

Requires features: gas_tank.manage

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Alert configuration updated

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/gas_tank/accounts/:id/alerts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/accounts/{id}/balance`

Get the current ledger balance for a specific gas tank account

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Balance returned

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/accounts/:id/balance" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/accounts/{id}/transactions`

List ledger transactions for a specific gas tank account

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Paginated list of transactions

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/accounts/:id/transactions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/portal/accounts`

List active gas tank accounts with balances for the authenticated customer

**Tags:** Customer Portal, Wallet

### Responses

**200** – List of accounts with balances

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/accounts" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/accounts/{id}/alerts`

Get alert configuration for a gas tank account (returns defaults if not configured)

**Tags:** Customer Portal, Wallet

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Alert configuration

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/accounts/:id/alerts" \
  -H "Accept: application/json"
```

## PUT `/gas_tank/portal/accounts/{id}/alerts`

Upsert alert configuration for a gas tank account

**Tags:** Customer Portal, Wallet

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Alert configuration updated

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Account not found

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/gas_tank/portal/accounts/:id/alerts" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/deposit-address`

Get deposit address for a chain and environment

**Tags:** Wallet

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/deposit-address" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/stats`

Get aggregated gas tank statistics for the authenticated customer

**Tags:** Customer Portal, Wallet

### Responses

**200** – Aggregated gas tank statistics

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/stats" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/transactions`

List gas tank transactions for the authenticated customer

**Tags:** Customer Portal, Wallet

### Responses

**200** – Paginated list of transactions

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/transactions" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/usage`

Get gas tank usage aggregates for the authenticated customer

**Tags:** Customer Portal, Wallet

### Responses

**200** – Usage aggregates with per-chain breakdown

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/usage" \
  -H "Accept: application/json"
```

## POST `/gas_tank/portal/wallet-topup`

Record a wallet-broadcast deposit TX for gas tank tracking

**Tags:** Wallet

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/gas_tank/portal/wallet-topup" \
  -H "Accept: application/json"
```

## GET `/gas_tank/portal/withdraw`

Poll withdrawal payout status by holdId

**Tags:** Customer Portal, Wallet

### Responses

**200** – Payout record with status and tx_hash, or null if not found

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – holdId is required

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/portal/withdraw" \
  -H "Accept: application/json"
```

## POST `/gas_tank/portal/withdraw`

Initiate a gas tank withdrawal via the customer portal (async workflow)

**Tags:** Customer Portal, Wallet

### Responses

**202** – Withdrawal dispatched; returns holdId for status polling

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Validation failed or insufficient balance

Content-Type: `application/json`

**429** – Rate limit exceeded

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/gas_tank/portal/withdraw" \
  -H "Accept: application/json"
```

## GET `/gas_tank/stats`

Aggregate balance stats across all active gas tank accounts

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Responses

**200** – Aggregated stats returned

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/stats" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/transactions`

List all ledger transactions scoped to the gas tank with enrichment and CSV export

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Responses

**200** – Paginated list of enriched transactions or CSV export

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/transactions" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/usage`

Get gas tank usage aggregates for the authenticated tenant

Requires features: gas_tank.view

**Tags:** Wallet

**Requires authentication.**

**Features:** gas_tank.view

### Responses

**200** – Usage aggregates with per-chain breakdown

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/usage" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/gas_tank/withdraw`

Poll withdrawal payout status by hold_id

Requires features: gas_tank.withdraw

**Tags:** Gas Tank

**Requires authentication.**

**Features:** gas_tank.withdraw

### Responses

**200** – Payout record with status and tx_hash, or null if not found

Content-Type: `application/json`

**422** – hold_id is required

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/gas_tank/withdraw" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/gas_tank/withdraw`

Initiate a gas tank withdrawal via API key (async workflow)

Requires features: gas_tank.withdraw

**Tags:** Gas Tank

**Requires authentication.**

**Features:** gas_tank.withdraw

### Responses

**202** – Withdrawal dispatched; returns hold_id for status polling

Content-Type: `application/json`

**422** – Invalid payload or insufficient balance

Content-Type: `application/json`

**429** – Rate limit exceeded

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/gas_tank/withdraw" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/integrations`

List integrations

Returns a paginated collection of integrations.

Requires features: integrations.view

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.view

### Responses

**200** – Paginated integrations

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "string",
      "title": "string",
      "category": null,
      "hub": null,
      "providerKey": null,
      "bundleId": null,
      "hasCredentials": true,
      "isEnabled": true,
      "apiVersion": null
    }
  ],
  "total": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/integrations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/integrations/{id}`

Get integration detail

Requires features: integrations.view

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/integrations/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/integrations/{id}/credentials`

Get or save integration credentials

Requires features: integrations.credentials.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.credentials.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/integrations/:id/credentials" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/integrations/{id}/credentials`

Get or save integration credentials

Requires features: integrations.credentials.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.credentials.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/integrations/:id/credentials" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/integrations/{id}/health`

Run health check for an integration

Requires features: integrations.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/integrations/:id/health" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/integrations/{id}/state`

Update integration state

Requires features: integrations.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/integrations/:id/state" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/integrations/{id}/version`

Change integration API version

Requires features: integrations.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/integrations/:id/version" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/integrations/logs`

List integration logs

Requires features: integrations.manage

**Tags:** Integrations

**Requires authentication.**

**Features:** integrations.manage

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/integrations/logs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/messages`

List messages

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| folder | query | any | Optional |
| status | query | any | Optional |
| type | query | any | Optional |
| visibility | query | any | Optional |
| sourceEntityType | query | any | Optional |
| sourceEntityId | query | any | Optional |
| externalEmail | query | any | Optional |
| hasObjects | query | any | Optional |
| hasAttachments | query | any | Optional |
| hasActions | query | any | Optional |
| senderId | query | any | Optional |
| search | query | any | Optional |
| since | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |

### Responses

**200** – Message list

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "type": "string",
      "visibility": null,
      "sourceEntityType": null,
      "sourceEntityId": null,
      "externalEmail": null,
      "externalName": null,
      "subject": "string",
      "bodyPreview": "string",
      "senderUserId": "00000000-0000-4000-8000-000000000000",
      "senderName": null,
      "senderEmail": null,
      "priority": "string",
      "status": "string",
      "hasObjects": true,
      "objectCount": 1,
      "hasAttachments": true,
      "attachmentCount": 1,
      "recipientCount": 1,
      "hasActions": true,
      "actionTaken": null,
      "sentAt": null,
      "readAt": null,
      "threadId": null
    }
  ],
  "page": 1,
  "pageSize": 1,
  "total": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages?folder=inbox&page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/messages`

Compose a message

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Request Body

Content-Type: `application/json`

```json
{
  "type": "default",
  "visibility": null,
  "recipients": [],
  "subject": "",
  "body": "",
  "bodyFormat": "text",
  "priority": "normal",
  "sendViaEmail": false,
  "isDraft": false
}
```

### Responses

**201** – Message created

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "threadId": null
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/messages" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"type\": \"default\",
  \"visibility\": null,
  \"recipients\": [],
  \"subject\": \"\",
  \"body\": \"\",
  \"bodyFormat\": \"text\",
  \"priority\": \"normal\",
  \"sendViaEmail\": false,
  \"isDraft\": false
}"
```

## DELETE `/messages/{id}`

Delete message for current sender/recipient context

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/messages/{id}`

Get message detail

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message detail with actor-visible thread items only

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "type": "string",
  "isDraft": true,
  "canEditDraft": true,
  "visibility": null,
  "sourceEntityType": null,
  "sourceEntityId": null,
  "externalEmail": null,
  "externalName": null,
  "typeDefinition": {
    "labelKey": "string",
    "icon": "string",
    "color": null,
    "allowReply": true,
    "allowForward": true,
    "ui": null
  },
  "threadId": null,
  "parentMessageId": null,
  "senderUserId": "00000000-0000-4000-8000-000000000000",
  "senderName": null,
  "senderEmail": null,
  "subject": "string",
  "body": "string",
  "bodyFormat": "text",
  "priority": "string",
  "sentAt": null,
  "actionData": null,
  "actionTaken": null,
  "actionTakenAt": null,
  "actionTakenByUserId": null,
  "recipients": [
    {
      "userId": "00000000-0000-4000-8000-000000000000",
      "type": "to",
      "status": "string",
      "readAt": null
    }
  ],
  "objects": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entityModule": "string",
      "entityType": "string",
      "entityId": "00000000-0000-4000-8000-000000000000",
      "actionRequired": true,
      "actionType": null,
      "actionLabel": null,
      "snapshot": null,
      "preview": null
    }
  ],
  "thread": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "senderUserId": "00000000-0000-4000-8000-000000000000",
      "senderName": null,
      "senderEmail": null,
      "body": "string",
      "sentAt": null
    }
  ],
  "isRead": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PATCH `/messages/{id}`

Update draft message

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "visibility": null
}
```

### Responses

**200** – Draft updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Only drafts can be edited

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PATCH "https://apiv2.tronergy.io/messages/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"visibility\": null
}"
```

## POST `/messages/{id}/actions/{actionId}`

Execute message action

Requires features: messages.actions

**Tags:** Messages

**Requires authentication.**

**Features:** messages.actions

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |
| actionId | path | any | Required |

### Request Body

Content-Type: `application/json`

No example available for this content type.

### Responses

**200** – Action executed

Content-Type: `application/json`

```json
{
  "ok": true,
  "actionId": "string"
}
```

**404** – Action not found

Content-Type: `application/json`

**409** – Action already taken

Content-Type: `application/json`

**410** – Action expired

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/messages/:id/actions/:actionId" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/messages/{id}/archive`

Unarchive message

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message unarchived

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id/archive" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/messages/{id}/archive`

Archive message

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message archived

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/messages/:id/archive" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/messages/{id}/attachments`

Unlink attachments from draft message

Requires features: messages.attach_files

**Tags:** Messages

**Requires authentication.**

**Features:** messages.attach_files

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Attachments unlinked

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Only draft messages can be edited

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## GET `/messages/{id}/attachments`

List message attachments

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Attachments

Content-Type: `application/json`

```json
{
  "attachments": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "fileName": "string",
      "fileSize": 1,
      "mimeType": "string",
      "url": "string"
    }
  ]
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/:id/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/messages/{id}/attachments`

Link attachments to draft message

Requires features: messages.attach_files

**Tags:** Messages

**Requires authentication.**

**Features:** messages.attach_files

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "attachmentIds": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
```

### Responses

**200** – Attachments linked

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Only draft messages can be edited

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/messages/:id/attachments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"attachmentIds\": [
    \"00000000-0000-4000-8000-000000000000\"
  ]
}"
```

## GET `/messages/{id}/confirmation`

Read message confirmation status

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Confirmation status

Content-Type: `application/json`

```json
{
  "messageId": "00000000-0000-4000-8000-000000000000",
  "confirmed": true,
  "confirmedAt": null,
  "confirmedByUserId": null
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/:id/confirmation" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/messages/{id}/conversation`

Delete conversation for current actor

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Conversation deleted

Content-Type: `application/json`

```json
{
  "ok": true,
  "affectedCount": 1
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id/conversation" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/messages/{id}/conversation/archive`

Archive conversation for current actor

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Conversation archived

Content-Type: `application/json`

```json
{
  "ok": true,
  "affectedCount": 1
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/messages/:id/conversation/archive" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/messages/{id}/conversation/read`

Mark entire conversation as unread for current actor

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Conversation marked unread

Content-Type: `application/json`

```json
{
  "ok": true,
  "affectedCount": 1
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id/conversation/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/messages/{id}/forward`

Forward a message and optionally include attachments from the forwarded conversation slice

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "recipients": [
    {
      "userId": "00000000-0000-4000-8000-000000000000",
      "type": "to"
    }
  ],
  "includeAttachments": true,
  "sendViaEmail": false
}
```

### Responses

**201** – Message forwarded

Content-Type: `application/json`

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

**404** – Message not found

Content-Type: `application/json`

**409** – Forward not allowed for message type

Content-Type: `application/json`

**413** – Forward body exceeds maximum length

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/messages/:id/forward" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"recipients\": [
    {
      \"userId\": \"00000000-0000-4000-8000-000000000000\",
      \"type\": \"to\"
    }
  ],
  \"includeAttachments\": true,
  \"sendViaEmail\": false
}"
```

## GET `/messages/{id}/forward-preview`

Get forward preview for a message

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Forward preview generated

Content-Type: `application/json`

```json
{
  "subject": "string",
  "body": "string"
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**413** – Forward body exceeds maximum length

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/:id/forward-preview" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/messages/{id}/read`

Mark message as unread

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message marked unread

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/messages/:id/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/messages/{id}/read`

Mark message as read

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Message marked read

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/messages/:id/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/messages/{id}/reply`

Reply to message

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "body": "string",
  "bodyFormat": "text",
  "replyAll": false,
  "sendViaEmail": false
}
```

### Responses

**201** – Reply created

Content-Type: `application/json`

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

**404** – Message not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – No recipients available for reply

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/messages/:id/reply" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"body\": \"string\",
  \"bodyFormat\": \"text\",
  \"replyAll\": false,
  \"sendViaEmail\": false
}"
```

## GET `/messages/object-types`

List registered message object types for a message type

Requires features: messages.compose

**Tags:** Messages

**Requires authentication.**

**Features:** messages.compose

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| messageType | query | any | Required |

### Responses

**200** – Message object types

Content-Type: `application/json`

```json
{
  "items": [
    {
      "module": "string",
      "entityType": "string",
      "labelKey": "string",
      "icon": "string",
      "actions": [
        {
          "id": "string",
          "labelKey": "string"
        }
      ]
    }
  ]
}
```

**400** – Invalid query

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/object-types?messageType=string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/messages/token/{token}`

Access message via token

**Tags:** Messages

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| token | path | any | Required |

### Responses

**200** – Message detail via token

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "type": "string",
  "subject": "string",
  "body": "string",
  "bodyFormat": "text",
  "priority": "low",
  "senderUserId": "00000000-0000-4000-8000-000000000000",
  "sentAt": null,
  "actionData": null,
  "actionTaken": null,
  "actionTakenAt": null,
  "actionTakenByUserId": null,
  "objects": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "entityModule": "string",
      "entityType": "string",
      "entityId": "00000000-0000-4000-8000-000000000000",
      "actionRequired": true,
      "actionType": null,
      "actionLabel": null,
      "snapshot": null
    }
  ],
  "requiresAuth": true,
  "recipientUserId": "00000000-0000-4000-8000-000000000000"
}
```

**404** – Invalid or expired link

Content-Type: `application/json`

**409** – Token usage exceeded

Content-Type: `application/json`

**410** – Token expired

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/token/:token" \
  -H "Accept: application/json"
```

## GET `/messages/types`

List registered message types

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Responses

**200** – Message types

Content-Type: `application/json`

```json
{
  "items": [
    {
      "type": "string",
      "module": "string",
      "labelKey": "string",
      "icon": "string",
      "color": null,
      "allowReply": true,
      "allowForward": true,
      "actionsExpireAfterHours": null,
      "ui": null
    }
  ]
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/types" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/messages/unread-count`

Get unread message count

Requires features: messages.view

**Tags:** Messages

**Requires authentication.**

**Features:** messages.view

### Responses

**200** – Unread count

Content-Type: `application/json`

```json
{
  "unreadCount": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/messages/unread-count" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/notifications`

List notifications

Returns a paginated collection of notifications.

**Tags:** Notifications

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| status | query | any | Optional |
| type | query | any | Optional |
| severity | query | any | Optional |
| sourceEntityType | query | any | Optional |
| sourceEntityId | query | any | Optional |
| since | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| ids | query | any | Optional. Comma-separated list of record UUIDs to filter by (max 200). |

### Responses

**200** – Paginated notifications

Content-Type: `application/json`

```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

```bash
curl -X GET "https://apiv2.tronergy.io/notifications?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/notifications`

Create notification

Creates a notification for a user.

Requires features: notifications.create

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.create

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – Notification created

Content-Type: `application/json`

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

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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`

POST /notifications/{id}/action

**Tags:** Notifications

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/notifications/:id/action" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/notifications/{id}/dismiss`

PUT /notifications/{id}/dismiss

**Tags:** Notifications

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/notifications/:id/dismiss" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/notifications/{id}/read`

PUT /notifications/{id}/read

**Tags:** Notifications

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/notifications/:id/read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/notifications/{id}/restore`

PUT /notifications/{id}/restore

**Tags:** Notifications

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/notifications/:id/restore" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/notifications/batch`

POST /notifications/batch

Requires features: notifications.create

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.create

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/notifications/batch" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/notifications/feature`

POST /notifications/feature

Requires features: notifications.create

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.create

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/notifications/feature" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/notifications/mark-all-read`

PUT /notifications/mark-all-read

**Tags:** Notifications

**Requires authentication.**

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/notifications/mark-all-read" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/notifications/role`

POST /notifications/role

Requires features: notifications.create

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.create

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/notifications/role" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/notifications/settings`

GET /notifications/settings

Requires features: notifications.manage

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.manage

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/notifications/settings`

POST /notifications/settings

Requires features: notifications.manage

**Tags:** Notifications

**Requires authentication.**

**Features:** notifications.manage

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/notifications/settings" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/notifications/unread-count`

GET /notifications/unread-count

**Tags:** Notifications

**Requires authentication.**

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/notifications/unread-count" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/onboarding/onboarding`

Self-service onboarding submission

**Tags:** Onboarding

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/onboarding/onboarding" \
  -H "Accept: application/json"
```

## GET `/onboarding/onboarding/verify`

Onboarding verification redirect

**Tags:** Onboarding

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/onboarding/onboarding/verify" \
  -H "Accept: application/json"
```

## GET `/payment_gateways/payments`

List payments with filters and pagination

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Responses

**200** – Paginated list of payments

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/payments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments`

Create a payment (async via Inngest workflow)

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Responses

**202** – Payment creation accepted for async processing

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/payments/{id}`

Get a single payment with its transaction history

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Payment with transactions returned

Content-Type: `application/json`

**404** – Payment not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/payments/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments/{id}/authorize`

Authorize a payment (async via Inngest workflow)

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**202** – Authorization accepted for async processing

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments/:id/authorize" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments/{id}/cancel`

Cancel/void a payment (synchronous)

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Payment canceled successfully

Content-Type: `application/json`

**404** – Payment not found

Content-Type: `application/json`

**409** – Payment cannot be canceled in its current status

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments/:id/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments/{id}/capture`

Capture an authorized payment (async via Inngest workflow)

Requires features: payment_gateways.capture

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.capture

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**202** – Capture accepted for async processing

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments/:id/capture" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments/{id}/reconcile`

Clear reconciliation flag and create audit transaction

Requires features: payment_gateways.reconcile

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.reconcile

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Payment reconciled successfully

Content-Type: `application/json`

**404** – Payment not found

Content-Type: `application/json`

**409** – Payment does not require reconciliation

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments/:id/reconcile" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payments/{id}/refund`

Refund a captured payment (async via Inngest workflow)

Requires features: payment_gateways.refund

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.refund

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**202** – Refund accepted for async processing

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payments/:id/refund" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/payouts`

List payouts with filters and pagination

Requires features: payment_gateways.view_payouts

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view_payouts

### Responses

**200** – Paginated list of payouts

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/payouts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payouts`

Create a payout (async via Inngest workflow)

Requires features: payment_gateways.create_payout

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.create_payout

### Responses

**202** – Payout creation accepted for async processing

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payouts" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/payouts/{id}`

Get a single payout with its transaction history

Requires features: payment_gateways.view_payouts

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view_payouts

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Payout with transactions returned

Content-Type: `application/json`

**404** – Payout not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/payouts/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/payouts/{id}/cancel`

Cancel a pending payout (synchronous)

Requires features: payment_gateways.cancel_payout

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.cancel_payout

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Payout canceled successfully

Content-Type: `application/json`

**404** – Payout not found

Content-Type: `application/json`

**409** – Payout cannot be canceled (invalid status transition)

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/payouts/:id/cancel" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/portal/deposit`

Get customer deposit address and latest status snapshot

**Tags:** Customer Portal, Payment Gateways

### Responses

**200** – Resolved customer deposit address and latest payment state

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid chain or provider not enabled

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/portal/deposit" \
  -H "Accept: application/json"
```

## POST `/payment_gateways/portal/deposit`

Resolve customer permanent deposit address and latest status snapshot

**Tags:** Customer Portal, Payment Gateways

### Responses

**200** – Resolved customer deposit address and latest payment state

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Validation failed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/portal/deposit" \
  -H "Accept: application/json"
```

## DELETE `/payment_gateways/providers`

Deactivate a payment provider (soft delete)

Soft-deletes a payment provider by ID.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Provider identifier |

### Responses

**200** – Provider deactivated

Content-Type: `application/json`

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

**404** – Provider not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/payment_gateways/providers?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/providers`

List payment providers

Returns paginated payment providers for the current tenant with optional provider_key filter.

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| provider_key | query | any | Optional |

### Responses

**200** – Paginated list of payment providers

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "providerKey": "string",
      "isEnabled": true,
      "isPollingEnabled": true,
      "pollingInterval": 1,
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/providers?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/providers`

Register a payment provider

Creates a new payment provider configuration for the current tenant.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Request Body

Content-Type: `application/json`

```json
{
  "provider_key": "string",
  "is_enabled": true,
  "is_polling_enabled": false,
  "polling_interval": 60000
}
```

### Responses

**201** – Provider created

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "providerKey": "string",
  "isEnabled": true,
  "isPollingEnabled": true,
  "pollingInterval": 1,
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "createdAt": "string",
  "updatedAt": "string"
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Provider key already exists for this tenant

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/providers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"provider_key\": \"string\",
  \"is_enabled\": true,
  \"is_polling_enabled\": false,
  \"polling_interval\": 60000
}"
```

## PUT `/payment_gateways/providers`

Update a payment provider

Updates an existing payment provider configuration.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Provider updated

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "providerKey": "string",
  "isEnabled": true,
  "isPollingEnabled": true,
  "pollingInterval": 1,
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "createdAt": "string",
  "updatedAt": "string"
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Provider not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/payment_gateways/providers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## DELETE `/payment_gateways/refund-reasons`

Deactivate a refund reason (soft delete)

Soft-deletes a refund reason by ID.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | query | any | Required. Refund reason identifier |

### Responses

**200** – Refund reason deactivated

Content-Type: `application/json`

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

**404** – Refund reason not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/payment_gateways/refund-reasons?id=00000000-0000-4000-8000-000000000000" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/refund-reasons`

List refund reasons

Returns paginated refund reasons for the current tenant with optional is_active filter.

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| is_active | query | any | Required |

### Responses

**200** – Paginated list of refund reasons

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "code": "string",
      "label": "string",
      "isActive": true,
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string",
      "updatedAt": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/refund-reasons?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/refund-reasons`

Create a refund reason

Creates a new refund reason with a unique code per tenant.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Request Body

Content-Type: `application/json`

```json
{
  "code": "string",
  "label": "string",
  "is_active": true
}
```

### Responses

**201** – Refund reason created

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "label": "string",
  "isActive": true,
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "createdAt": "string",
  "updatedAt": "string"
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**409** – Code already exists for this tenant

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/refund-reasons" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"code\": \"string\",
  \"label\": \"string\",
  \"is_active\": true
}"
```

## PUT `/payment_gateways/refund-reasons`

Update a refund reason

Updates an existing refund reason.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – Refund reason updated

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "code": "string",
  "label": "string",
  "isActive": true,
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "createdAt": "string",
  "updatedAt": "string"
}
```

**400** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Refund reason not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/payment_gateways/refund-reasons" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"00000000-0000-4000-8000-000000000000\"
}"
```

## POST `/payment_gateways/sync`

Manually trigger transaction sync for all or a specific provider

Enqueues a sync-transactions job. Optionally filter by provider_key.

Requires features: payment_gateways.manage

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.manage

### Request Body

Content-Type: `application/json`

```json
{}
```

### Responses

**200** – Sync job enqueued

Content-Type: `application/json`

```json
{
  "status": "enqueued"
}
```

**422** – Invalid payload

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/sync" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{}"
```

## GET `/payment_gateways/transactions`

List transactions

Returns paginated, append-only transaction records. Transactions are created internally by workflows and workers and cannot be modified via API.

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| payment_id | query | any | Optional |
| payout_id | query | any | Optional |
| type | query | any | Optional |
| status | query | any | Optional |

### Responses

**200** – Paginated list of transactions

Content-Type: `application/json`

```json
{
  "items": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "paymentId": null,
      "payoutId": null,
      "type": "authorization",
      "status": "succeeded",
      "amount": "string",
      "externalId": null,
      "idempotencyKey": "string",
      "data": null,
      "note": null,
      "refundReasonId": null,
      "organizationId": "00000000-0000-4000-8000-000000000000",
      "tenantId": "00000000-0000-4000-8000-000000000000",
      "createdAt": "string"
    }
  ],
  "total": 1,
  "page": 1,
  "pageSize": 1,
  "totalPages": 1
}
```

**422** – Invalid query parameters

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/transactions?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/payment_gateways/transactions/{id}`

Get transaction by ID

Returns a single append-only transaction record scoped to the current tenant and organization.

Requires features: payment_gateways.view

**Tags:** Payment Gateways

**Requires authentication.**

**Features:** payment_gateways.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Transaction detail

Content-Type: `application/json`

```json
{
  "id": "00000000-0000-4000-8000-000000000000",
  "paymentId": null,
  "payoutId": null,
  "type": "authorization",
  "status": "succeeded",
  "amount": "string",
  "externalId": null,
  "idempotencyKey": "string",
  "data": null,
  "note": null,
  "refundReasonId": null,
  "organizationId": "00000000-0000-4000-8000-000000000000",
  "tenantId": "00000000-0000-4000-8000-000000000000",
  "createdAt": "string"
}
```

**404** – Transaction not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/payment_gateways/transactions/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/payment_gateways/webhook/{provider}`

Receive webhook events from payment providers

**Tags:** Payment Gateways

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| provider | path | any | Required |

### Responses

**200** – Webhook received and queued for processing

Content-Type: `application/json`

**404** – Unknown provider key

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/payment_gateways/webhook/:provider" \
  -H "Accept: application/json"
```

## GET `/progress/active`

GET /progress/active

**Tags:** Progress

**Requires authentication.**

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/progress/active" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/progress/jobs`

List progressjobs

Returns a paginated collection of progressjobs scoped to the authenticated tenant.

**Tags:** Progress

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| status | query | any | Optional |
| jobType | query | any | Optional |
| parentJobId | query | any | Optional |
| includeCompleted | query | any | Optional |
| completedSince | query | any | Optional |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| search | query | any | Optional |
| sortField | query | any | Optional |
| sortDir | query | any | Optional |
| ids | query | any | Optional. Comma-separated list of record UUIDs to filter by (max 200). |

### Responses

**200** – Paginated progressjobs

Content-Type: `application/json`

```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

```bash
curl -X GET "https://apiv2.tronergy.io/progress/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/progress/jobs`

Create progressjob

Creates a new progress job for tracking a long-running operation.

Requires features: progress.create

**Tags:** Progress

**Requires authentication.**

**Features:** progress.create

### Request Body

Content-Type: `application/json`

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

### Responses

**201** – ProgressJob created

Content-Type: `application/json`

```json
{
  "id": null
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/progress/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"jobType\": \"string\",
  \"name\": \"string\",
  \"cancellable\": false
}"
```

## DELETE `/progress/jobs/{id}`

DELETE /progress/jobs/{id}

Requires features: progress.cancel

**Tags:** Progress

**Requires authentication.**

**Features:** progress.cancel

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**204** – Success

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/progress/jobs/{id}`

GET /progress/jobs/{id}

**Tags:** Progress

**Requires authentication.**

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/progress/jobs/{id}`

PUT /progress/jobs/{id}

Requires features: progress.update

**Tags:** Progress

**Requires authentication.**

**Features:** progress.update

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/progress/jobs/:id" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/query_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

**Tags:** Query Index

**Requires authentication.**

**Features:** query_index.purge

### Request Body

Content-Type: `application/json`

```json
{
  "entityType": "string"
}
```

### Responses

**200** – Purge job accepted.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity type

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/query_index/purge" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
```

## POST `/query_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

**Tags:** Query Index

**Requires authentication.**

**Features:** query_index.reindex

### Request Body

Content-Type: `application/json`

```json
{
  "entityType": "string"
}
```

### Responses

**200** – Reindex job accepted.

Content-Type: `application/json`

```json
{
  "ok": true
}
```

**400** – Missing entity type

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/query_index/reindex" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"entityType\": \"string\"
}"
```

## GET `/query_index/status`

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

**Tags:** Query Index

**Requires authentication.**

**Features:** query_index.status.view

### Responses

**200** – Current query index status.

Content-Type: `application/json`

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

**400** – Tenant or organization context required

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/query_index/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/relayer_tron/delegations`

List energy delegations with filters and pagination

Requires features: relayer_tron.view

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.view

### Responses

**200** – Paginated list of delegations

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/delegations" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/delegations/{id}/reclaim`

Manually reclaim delegated energy

Requires features: relayer_tron.manage

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Request Body

Content-Type: `application/json`

```json
{
  "force": false
}
```

### Responses

**200** – Delegation reclaimed successfully

Content-Type: `application/json`

**404** – Delegation not found

Content-Type: `application/json`

**409** – Delegation not in a reclaimable status or not yet expired

Content-Type: `application/json`

**422** – Invalid request body

Content-Type: `application/json`

**503** – Service configuration error (missing credentials)

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/delegations/:id/reclaim" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"force\": false
}"
```

## DELETE `/relayer_tron/pools`

Deactivate an energy pool (soft delete)

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**200** – Pool deactivated

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/relayer_tron/pools" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/relayer_tron/pools`

List tenant energy pools with filters and pagination

Requires features: relayer_tron.view

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.view

### Responses

**200** – Paginated list of pools

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/pools" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/pools`

Create a new tenant energy pool

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**201** – Pool created

Content-Type: `application/json`

**409** – Pool already exists for this tenant

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/pools" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/relayer_tron/pools`

Update an energy pool

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**200** – Pool updated

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/relayer_tron/pools" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/pools/{id}/refresh`

Fetch fresh on-chain resources and update pool energy/staking fields

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Pool refreshed with latest on-chain data

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/pools/:id/refresh" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/relayer_tron/pools/{id}/status`

Return staked TRX, total energy and available energy for the pool

Requires features: relayer_tron.view

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Pool resource status returned

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/pools/:id/status" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/pools/confirm-permission`

Confirm that the permission transaction has been confirmed on-chain and activate the pool

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**200** – Pool permission confirmed and pool activated

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**422** – Invalid payload or tx not confirmed after retries

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/pools/confirm-permission" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/pools/generate-permission-tx`

Build an unsigned AccountPermissionUpdate tx to grant delegate rights

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**200** – Unsigned tx and permission ID returned

Content-Type: `application/json`

**404** – Staking account not found on chain

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/pools/generate-permission-tx" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/relayer_tron/pools/validate-address`

Validate a staking address — checks on-chain staking state

Requires features: relayer_tron.pools

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.pools

### Responses

**200** – Validation result returned

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/pools/validate-address" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/relayer_tron/portal/delegations`

List energy delegations for the authenticated customer

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Paginated list of energy delegations

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/portal/delegations" \
  -H "Accept: application/json"
```

## GET `/relayer_tron/portal/pools`

List tenant energy pools for the authenticated customer

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Paginated list of tenant pools

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid query parameters

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/portal/pools" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools`

Create a new pending pool for the authenticated customer

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Pending pool returned (resume flow)

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**409** – Pool already exists for tenant

Content-Type: `application/json`

**422** – Invalid payload or staking address

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools" \
  -H "Accept: application/json"
```

## DELETE `/relayer_tron/portal/pools/{id}`

Soft-delete a tenant pool

**Tags:** Customer Portal, TronRelayer

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Pool deleted

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**409** – Cannot delete pool with active delegations

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/relayer_tron/portal/pools/:id" \
  -H "Accept: application/json"
```

## GET `/relayer_tron/portal/pools/{id}`

Get a single tenant pool with recent delegations for the authenticated customer

**Tags:** Customer Portal, TronRelayer

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Pool details with delegations

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/portal/pools/:id" \
  -H "Accept: application/json"
```

## PUT `/relayer_tron/portal/pools/{id}`

Update a tenant pool (status, threshold settings)

**Tags:** Customer Portal, TronRelayer

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |

### Responses

**200** – Pool updated

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

**502** – Upstream service failure

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/relayer_tron/portal/pools/:id" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools/activate-with-permission`

Activate a pending pool by verifying an existing on-chain permission (no TX hash needed)

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Pool activated with the specified permission

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool or staking account not found

Content-Type: `application/json`

**422** – Invalid payload, pool not pending, or permission incompatible

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools/activate-with-permission" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools/confirm-permission`

Confirm on-chain permission transaction and activate the pool

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Pool permission confirmed and pool activated

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool not found

Content-Type: `application/json`

**422** – Invalid payload, pool not pending, or tx not confirmed

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools/confirm-permission" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools/generate-permission-tx`

Build an unsigned AccountPermissionUpdate tx to grant delegate rights for a pending pool

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Unsigned tx and permission ID returned

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Pool or staking account not found

Content-Type: `application/json`

**422** – Invalid payload or pool not pending

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools/generate-permission-tx" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools/list-permissions`

Fetch active permissions from chain and analyze compatibility with the platform relayer

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – List of permissions with compatibility analysis

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**404** – Staking account not found on chain

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools/list-permissions" \
  -H "Accept: application/json"
```

## POST `/relayer_tron/portal/pools/validate-address`

Validate a Tron staking address for pool onboarding

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Validation result returned

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

**422** – Invalid payload

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/relayer_tron/portal/pools/validate-address" \
  -H "Accept: application/json"
```

## GET `/relayer_tron/portal/stats`

Get aggregated Tron relayer statistics for the authenticated customer

**Tags:** Customer Portal, TronRelayer

### Responses

**200** – Aggregated relayer statistics

Content-Type: `application/json`

**401** – Not authenticated

Content-Type: `application/json`

**403** – Insufficient permissions

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/portal/stats" \
  -H "Accept: application/json"
```

## GET `/relayer_tron/providers`

Return all registered marketplace energy providers with cached price and health status

Requires features: relayer_tron.view

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.view

### Responses

**200** – Provider list returned

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/providers" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/relayer_tron/stats`

Return aggregated pool, delegation, and provider stats for the tenant dashboard

Requires features: relayer_tron.view

**Tags:** TronRelayer

**Requires authentication.**

**Features:** relayer_tron.view

### Responses

**200** – Summary statistics returned

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/relayer_tron/stats" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## DELETE `/scheduler/jobs`

Delete scheduledjob

Deletes a scheduled job by ID.

Requires features: scheduler.jobs.manage

**Tags:** Scheduler

**Requires authentication.**

**Features:** scheduler.jobs.manage

### Request Body

Content-Type: `application/json`

```json
{
  "id": "string"
}
```

### Responses

**200** – ScheduledJob deleted

Content-Type: `application/json`

```json
{
  "ok": true
}
```

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/scheduler/jobs" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"
```

## GET `/scheduler/jobs`

List scheduledjobs

Returns a paginated collection of scheduledjobs scoped to the authenticated organization.

Requires features: scheduler.jobs.view

**Tags:** Scheduler

**Requires authentication.**

**Features:** scheduler.jobs.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| page | query | any | Optional |
| pageSize | query | any | Optional |
| id | query | any | Optional |
| search | query | any | Optional |
| scopeType | query | any | Optional |
| isEnabled | query | any | Required |
| sourceType | query | any | Optional |
| sourceModule | query | any | Optional |
| sort | query | any | Optional |
| order | query | any | Optional |
| ids | query | any | Optional. Comma-separated list of record UUIDs to filter by (max 200). |

### Responses

**200** – Paginated scheduledjobs

Content-Type: `application/json`

```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

```bash
curl -X GET "https://apiv2.tronergy.io/scheduler/jobs?page=1&pageSize=20" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## POST `/scheduler/jobs`

Create scheduledjob

Creates a new scheduled job with cron or interval-based scheduling.

Requires features: scheduler.jobs.manage

**Tags:** Scheduler

**Requires authentication.**

**Features:** scheduler.jobs.manage

### Request Body

Content-Type: `application/json`

```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

**201** – ScheduledJob created

Content-Type: `application/json`

```json
{
  "id": null
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/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`

Update scheduledjob

Updates an existing scheduled job by ID.

Requires features: scheduler.jobs.manage

**Tags:** Scheduler

**Requires authentication.**

**Features:** scheduler.jobs.manage

### Request Body

Content-Type: `application/json`

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

### Responses

**200** – ScheduledJob updated

Content-Type: `application/json`

```json
{
  "ok": true
}
```

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/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
}"
```

## GET `/scheduler/jobs/{id}/executions`

Get execution history for a schedule

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

**Tags:** Scheduler

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| id | path | any | Required |
| pageSize | query | any | Optional |

### Responses

**200** – Execution history

Content-Type: `application/json`

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

**400** – Local strategy not supported

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**401** – Unauthorized

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Access denied

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Schedule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Scheduler

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| jobId | path | any | Required |
| queue | query | any | Required |

### Responses

**200** – Job details and logs

Content-Type: `application/json`

```json
{
  "id": "string",
  "name": "string",
  "state": "waiting",
  "progress": null,
  "returnvalue": null,
  "failedReason": null,
  "stacktrace": null,
  "attemptsMade": 1,
  "processedOn": null,
  "finishedOn": null,
  "logs": [
    "string"
  ]
}
```

**400** – Invalid request or local strategy not supported

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**401** – Unauthorized

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Access denied

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Job not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**500** – Internal server error

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Scheduler

### Responses

**200** – Available targets

Content-Type: `application/json`

```json
{
  "queues": [
    {
      "value": "string",
      "label": "string"
    }
  ],
  "commands": [
    {
      "value": "string",
      "label": "string"
    }
  ]
}
```

**401** – Unauthorized

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/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.

**Tags:** Scheduler

### Request Body

Content-Type: `application/json`

```json
{
  "id": "string"
}
```

### Responses

**200** – Schedule triggered successfully

Content-Type: `application/json`

```json
{
  "ok": true,
  "jobId": "string",
  "message": "string"
}
```

**400** – Invalid request or local strategy not supported

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**401** – Unauthorized

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**403** – Access denied

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

**404** – Schedule not found

Content-Type: `application/json`

```json
{
  "error": "string"
}
```

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/scheduler/trigger" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{
  \"id\": \"string\"
}"
```

## DELETE `/translations/{entityType}/{entityId}`

Delete entity translations

Removes all translations for an entity.

Requires features: translations.manage

**Tags:** Translations

**Requires authentication.**

**Features:** translations.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityType | path | any | Required |
| entityId | path | any | Required |

### Responses

**204** – Translations deleted.

### Example

```bash
curl -X DELETE "https://apiv2.tronergy.io/translations/string/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/translations/{entityType}/{entityId}`

Get entity translations

Returns the full translation record for a single entity.

Requires features: translations.view

**Tags:** Translations

**Requires authentication.**

**Features:** translations.view

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityType | path | any | Required |
| entityId | path | any | Required |

### Responses

**200** – Translation record found.

Content-Type: `application/json`

**404** – No translations found for this entity

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/translations/string/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## PUT `/translations/{entityType}/{entityId}`

Create or update entity translations

Full replacement of translations JSONB for an entity.

Requires features: translations.manage

**Tags:** Translations

**Requires authentication.**

**Features:** translations.manage

### Parameters
| Name | Location | Type | Description |
| --- | --- | --- | --- |
| entityType | path | any | Required |
| entityId | path | any | Required |

### Responses

**200** – Translations saved.

Content-Type: `application/json`

**400** – Validation failed

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/translations/string/string" \
  -H "Accept: application/json" \
  -H "authorization: Bearer <token>"
```

## GET `/translations/locales`

List supported translation locales

**Tags:** Entity Translations

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/translations/locales" \
  -H "Accept: application/json"
```

## PUT `/translations/locales`

Update supported translation locales

**Tags:** Entity Translations

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X PUT "https://apiv2.tronergy.io/translations/locales" \
  -H "Accept: application/json"
```

## GET `/wallet_connections/portal/onboarding-status`

Get onboarding checklist status for the authenticated customer

**Tags:** Customer Portal

### Responses

**200** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X GET "https://apiv2.tronergy.io/wallet_connections/portal/onboarding-status" \
  -H "Accept: application/json"
```

## POST `/wallet_connections/portal/onboarding-status`

Update onboarding checklist status (dismiss or reset)

**Tags:** Customer Portal

### Responses

**201** – Success response

Content-Type: `application/json`

### Example

```bash
curl -X POST "https://apiv2.tronergy.io/wallet_connections/portal/onboarding-status" \
  -H "Accept: application/json"
```