# Chat

Part of AppEngine API Documentation. Full index: https://appengine.appmint.io/documentation.md
## POST /chat/engage

**Engage a website visitor**

`operationId: ChatController_engage`

Staff only. Pushes a notice or a chat invite into one visitor's widget, by the `deviceId` it reported (from Live View). Works whether or not the sender is connected to chat. Delivered over the widget's socket; nothing is stored.

#### Signature

```http
POST /chat/engage (body) -> { success: true, messageId }
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `403` | STAFF_ONLY | Sign in as staff to engage a visitor. | The caller is not a signed-in user. | — |
| `400` | DEVICE_REQUIRED | Say which visitor (deviceId). Their widget has not reported a device. | No deviceId. | — |

Plus the standard platform errors: `401`, `429`, `500`.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

```json
{
  "deviceId": "dev_7Kq2M9",
  "message": "Need help choosing a size?",
  "kind": "chat-invite"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | { success: true, messageId } |
| `400` | Say which visitor (deviceId). Their widget has not reported a device. — No deviceId. |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | Sign in as staff to engage a visitor. — The caller is not a signed-in user. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/ice-servers

**Get ICE servers**

`operationId: ChatController_getIceServers`

Returns the STUN and TURN servers a WebRTC client needs to establish a voice or video connection.

Fetch these when opening a call rather than caching them — TURN credentials are short-lived, and a stale set is the usual cause of a call that connects on the same network but fails across NAT.

#### Signature

```http
GET /chat/ice-servers () -> ICE server configuration
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- TURN credentials expire. Do not cache the response between sessions.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/live/{chatId}/{userId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | ICE server configuration |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/agents/online

**List online agents**

`operationId: ChatController_getOnlineAgents`

The agents currently available, optionally filtered by status or skill. The read behind a routing decision — who can take this chat right now.

#### Signature

```http
GET /chat/agents/online (status?: string, skill?: string) -> Online agents
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/agents/{email}/presence`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `status` | query | "available" \| "busy" \| "away" | — |  |
| `skill` | query | string | — | Restrict to agents with a skill. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Online agents |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/agents/{email}/presence

**Get an agent's presence**

`operationId: ChatController_getAgentPresence`

The current presence of one agent — whether they are online, their status, and how many chats they are handling.

#### Signature

```http
GET /chat/agents/{email}/presence (email: string) -> The agent's presence
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Agent not found | No agent has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/agents/{email}/status`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | Agent email address. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The agent's presence |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Agent not found — No agent has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/customers/online

**List online customers**

`operationId: ChatController_getOnlineCustomers`

Customers currently present on the site — who could be reached with a proactive chat invitation.

#### Signature

```http
GET /chat/customers/online () -> Online customers
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/customers/{email}/journey`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Online customers |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/customers/{email}/journey

**Get a customer's interaction journey**

`operationId: ChatController_getCustomerJourney`

The customer's full interaction history across channels — what an agent should read before answering, so the customer is not asked to repeat themselves.

`limit` caps how far back it goes.

#### Signature

```http
GET /chat/customers/{email}/journey (email: string, limit?: integer) -> The customer journey
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/messages/{email}/{createdAfter}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | Customer email. |
| `limit` | query | integer | — | How many interactions to return. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The customer journey |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/presence/stats

**Get presence statistics**

`operationId: ChatController_getPresenceStats`

Aggregate presence across the org — how many agents are online, by status. The staffing view against queue depth.

#### Signature

```http
GET /chat/presence/stats () -> Presence statistics
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/queue/stats`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Presence statistics |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/agents/{email}/status

**Set an agent's status**

`operationId: ChatController_setAgentStatus`

Sets an agent's availability. Only `available` agents receive routed chats — moving to `busy` or `away` takes them out of routing without disconnecting the chats they already hold.

#### Signature

```http
POST /chat/agents/{email}/status (email: string, body) -> The updated presence
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Existing chats are unaffected — this changes routing eligibility only.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Agent not found | No agent has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/agents/online`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | Agent email address. |

### Request body

The status to set.

```json
{
  "status": "busy"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The updated presence |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Agent not found — No agent has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/queue

**Get the chat queue**

`operationId: ChatController_getQueue`

The chats currently waiting, in the order they will be served.

#### Signature

```http
GET /chat/queue (name?: string) -> Queued chats
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/queue/stats`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `name` | query | string | — | Which queue. Omit for the default. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Queued chats |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/queue

**Enqueue a chat**

`operationId: ChatController_enqueueChat`

Puts a chat into the routing queue to wait for an agent.

Use `skill` to require a particular competency and `priority` to jump the line — a higher number is served sooner. `context` travels with the chat, so whatever the customer already told a bot arrives with them.

#### Signature

```http
POST /chat/queue (body) -> The queued chat, with its position
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- A `skill` no online agent has leaves the chat queued indefinitely — check `GET /chat/agents/online` before requiring one.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/queue/position/{chatId}`
- `DELETE /chat/queue/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

The chat to queue.

```json
{
  "chatId": "CHT-4821",
  "customerEmail": "ada@example.com",
  "customerName": "Ada Lovelace"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The queued chat, with its position |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/queue/stats

**Get queue statistics**

`operationId: ChatController_getQueueStats`

Depth and wait times for a queue — read alongside `presence/stats` to see whether waits are a staffing problem or a routing one.

#### Signature

```http
GET /chat/queue/stats (name?: string) -> Queue statistics
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/presence/stats`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `name` | query | string | — | Which queue. Omit for the default. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Queue statistics |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/queue/position/{chatId}

**Get a chat's queue position**

`operationId: ChatController_getQueuePosition`

Where a waiting chat sits in the queue — what a customer-facing "you are 3rd in line" indicator reads.

#### Signature

```http
GET /chat/queue/position/{chatId} (chatId: string, name?: string) -> The queue position
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Position moves as higher-priority chats are queued, so it can go up as well as down.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/queue`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |
| `name` | query | string | — | Which queue. Omit for the default. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The queue position |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## DELETE /chat/queue/{chatId}

**Remove a chat from the queue**

`operationId: ChatController_dequeueChat`

Dequeues a waiting chat — because the customer left, or because it was answered another way. The chat session itself is not ended by this.

#### Signature

```http
DELETE /chat/queue/{chatId} (chatId: string, name?: string) -> The dequeue result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/queue`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |
| `name` | query | string | — | Which queue. Omit for the default. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The dequeue result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/config/{chatId}

**Get chat configuration**

`operationId: ChatController_getChatConfig`

The configuration for a chat session — its routing, branding and behaviour settings.

#### Signature

```http
GET /chat/config/{chatId} (chatId: string) -> The chat configuration
```

#### Access

Public — no credentials required.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /chat/sessions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The chat configuration |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/get-profile/{userId}

**Get a chat user profile**

`operationId: ChatController_getUserProfile`

The profile of a chat participant — who the agent is actually talking to.

#### Signature

```http
GET /chat/get-profile/{userId} (userId: string) -> The user profile
```

#### Access

Public — no credentials required.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | User not found | No user has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `429`, `500`.

#### See also

- `GET /chat/customers/{email}/journey`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `userId` | path | string | yes | User identifier. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The user profile |
| `404` | User not found — No user has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/sessions

**Get active chat sessions**

`operationId: ChatController_activeSessions`

The chat sessions currently in progress across the org — the supervisor view of what is live right now.

#### Signature

```http
GET /chat/sessions () -> Active sessions
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/history/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | Active sessions |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/upload/{chatId}/{userId}

**Upload files to a chat**

`operationId: ChatController_upload`

Uploads one or more files into a chat session — screenshots, documents, whatever the customer needs to show. Multipart, and several files can be sent at once.

#### Signature

```http
POST /chat/upload/{chatId}/{userId} (chatId: string, userId: string, body) -> The uploaded files
```

#### Access

Public — no credentials required.

#### Notes

- This route does not read the `orgid` header — unlike the rest of the controller.

#### Errors

Plus the standard platform errors: `429`, `500`.

#### See also

- `POST /chat/live/{chatId}/{userId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization ID |
| `chatId` | path | string | yes | Chat session id. |
| `userId` | path | string | yes | Who is uploading. |

### Request body

Multipart form with one or more files.

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The uploaded files |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/live/{chatId}/{userId}

**Send a live chat message**

`operationId: ChatController_liveChat`

Sends a message into a live chat session.

Delivery to connected clients happens over WebSocket; this is the HTTP path for a client that cannot hold a socket open, and for server-side sends.

#### Signature

```http
POST /chat/live/{chatId}/{userId} (chatId: string, userId: string, body) -> The sent message
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/save/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |
| `userId` | path | string | yes | Who is sending. |

### Request body

The message to send.

```json
{
  "text": "Happy to help — can you confirm your order number?"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The sent message |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/messages/{email}/{createdAfter}

**Get a user's messages**

`operationId: ChatController_getUserMessages`

Every chat message for an email address, across sessions. Supply `createdAfter` to fetch only what has arrived since a point in time — the polling path for a client without a live socket.

#### Signature

```http
GET /chat/messages/{email}/{createdAfter} (email: string, createdAfter: string) -> The user's messages
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Omitting `createdAfter` returns the full history — always send it when polling.

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/history/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `email` | path | string | yes | User email. |
| `createdAfter` | path | string | yes | Return only messages after this timestamp. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The user's messages |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/history/{chatId}

**Get chat history**

`operationId: ChatController_getChatHistory`

Every message in one chat session, in order.

#### Signature

```http
GET /chat/history/{chatId} (chatId: string) -> The chat history
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/transcript/send`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The chat history |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/save/{chatId}

**Save a chat message**

`operationId: ChatController_saveMessage`

Persists a message to a chat's history without sending it live — for recording messages that arrived by another route, or reconstructing a transcript.

#### Signature

```http
POST /chat/save/{chatId} (chatId: string, body) -> The saved message
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Saves only — connected clients are not notified. Use `live` to actually deliver a message.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `POST /chat/live/{chatId}/{userId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |

### Request body

The message to store.

```json
{
  "userId": "ada@example.com",
  "text": "Is anyone there?"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | The saved message |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## PUT /chat/update/{chatId}

**Update a chat message**

`operationId: ChatController_updateMessage`

Edits a stored message. The transcript is what a dispute is settled on, so edit it only to correct a genuine error.

#### Signature

```http
PUT /chat/update/{chatId} (chatId: string, body) -> The updated message
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/history/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |
| `chatId` | path | string | yes | Chat session id. |

### Request body

The message to update.

```json
{
  "messageId": "MSG-9912",
  "text": "Corrected text"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `200` | The updated message |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## POST /chat/transcript/send

**Send a chat transcript**

`operationId: ChatController_sendTranscript`

Emails the full transcript of a conversation to an address — what a customer gets after a chat ends, and what an agent forwards when escalating.

The transcript is the whole conversation. Check it contains nothing that should not leave the org before sending it to an external address.

#### Signature

```http
POST /chat/transcript/send (body) -> Dispatch result
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Notes

- Sends the entire conversation, including anything an agent said assuming it was internal.

#### Errors

| Status | Code | Message | When | What to do |
| --- | --- | --- | --- | --- |
| `404` | NOT_FOUND | Chat not found | No chat has that identifier. | Check the identifier against the corresponding list endpoint. |

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/history/{chatId}`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Request body

Which chat, and where to send it.

```json
{
  "chatId": "CHT-4821",
  "email": "ada@example.com"
}
```

### Responses

| Status | Meaning |
| --- | --- |
| `201` | Dispatch result |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `404` | Chat not found — No chat has that identifier. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

## GET /chat/ai-active

**Check whether AI chat is active**

`operationId: ChatController_getActiveAiChats`

Whether the AI assistant is currently handling chats for this org — the flag a UI reads to decide whether to show "you are talking to an assistant".

#### Signature

```http
GET /chat/ai-active () -> AI chat state
```

#### Access

Requires a bearer JWT (`Authorization: Bearer <token>`).

#### Errors

Plus the standard platform errors: `401`, `403`, `429`, `500`.

#### See also

- `GET /chat/sessions`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `orgid` | header | string | yes | Organization (tenant) identifier. Every request is scoped to this org; data from other orgs is never visible. Issued with your API credentials. |

### Responses

| Status | Meaning |
| --- | --- |
| `200` | AI chat state |
| `401` | Authentication failed: Invalid or expired token — The `Authorization` header is missing, malformed, or the JWT has expired. |
| `403` | You do not have permission to perform this action — The caller is authenticated but lacks the role required by the endpoint, or is acting on another org. |
| `429` | Too Many Requests — More than 100,000 requests from one IP within 5 minutes (configurable per deployment). CORS preflights and requests from inside the platform cluster are not counted. The limiter answers before the error filter, so the body is `{ statusCode, error, message }` with no `path`, `method` or `timeStamp`; the `RateLimit-*` response headers say when the window resets. |
| `500` | An unexpected error occurred. Our team has been notified. — An unhandled server-side failure. |

