> For the complete documentation index, see [llms.txt](https://docs.scaleconnect.com.au/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.scaleconnect.com.au/api/rest-api/scaleapp-rest-api/support.md).

# Support

Support ticket system and help desk

## Save broker's AI chat history

> Saves a prompt and AI response pair. When user\_id is a client, the chat is stored against that client. When user\_id is the calling broker's own Supabase id (Broker Brain, which is loan-book wide and has no client), the chat is stored against broker\_supabase\_id with user\_id left null.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/support/broker/ai-history":{"post":{"description":"Saves a prompt and AI response pair. When user_id is a client, the chat is stored against that client. When user_id is the calling broker's own Supabase id (Broker Brain, which is loan-book wide and has no client), the chat is stored against broker_supabase_id with user_id left null.","operationId":"SupportController_saveAiHistory_v1","parameters":[],"responses":{"201":{"description":""}},"summary":"Save broker's AI chat history","tags":["Support"]}}}}
```

## List the client's broker conversations

> Powers the chat history screen. Returns the client-broker conversations, newest first, each with a preview of that conversation's last message. Works for both the client and broker.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/support/broker/messages":{"get":{"description":"Powers the chat history screen. Returns the client-broker conversations, newest first, each with a preview of that conversation's last message. Works for both the client and broker.","operationId":"SupportController_getBrokerConversations_v1","parameters":[],"responses":{"200":{"description":"Conversation previews: id, createdAt, updatedAt and lastMessage"}},"summary":"List the client's broker conversations","tags":["Support"]}}}}
```

## Start a new broker-client conversation

> Opens a new conversation for the client and deactivates the previous one, carrying the assigned broker across. Messages already persist as they are sent, so this is the only part of chat history that sending does not already cover.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/broker/messages":{"post":{"description":"Opens a new conversation for the client and deactivates the previous one, carrying the assigned broker across. Messages already persist as they are sent, so this is the only part of chat history that sending does not already cover.","operationId":"SupportController_startNewBrokerConversation_v1","parameters":[],"responses":{"201":{"description":"The newly opened conversation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Start a new broker-client conversation","tags":["Support"]}}}}
```

## Get user's support chat

> This endpoints is for mobile so that client's support chat can be loaded.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/my-chat":{"get":{"description":"This endpoints is for mobile so that client's support chat can be loaded.","operationId":"SupportController_getMyChat_v1","parameters":[],"responses":{"200":{"description":"Support chat details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Get user's support chat","tags":["Support"]}}}}
```

## Get the broker's own support chat (ScaleConnect)

> Powers the ScaleConnect support footer. Gets or creates the calling broker's own support thread (support\_chat = true, user\_id = the broker's user id) so it lands in the ScaleAdmin Support inbox like a client's. The broker is the user side of this thread: unread counts the staff (admin/agent) replies they have not read.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/broker/my-support-chat":{"get":{"description":"Powers the ScaleConnect support footer. Gets or creates the calling broker's own support thread (support_chat = true, user_id = the broker's user id) so it lands in the ScaleAdmin Support inbox like a client's. The broker is the user side of this thread: unread counts the staff (admin/agent) replies they have not read.","operationId":"SupportController_getBrokerOwnSupportChat_v1","parameters":[],"responses":{"200":{"description":"The broker's support chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Get the broker's own support chat (ScaleConnect)","tags":["Support"]}}}}
```

## Open a support ticket for the broker (ScaleConnect)

> Returns the broker's open support ticket, creating one when none exists. The panel calls this on the first send after a closed ticket or for a brand-new broker.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/broker/my-support-chat":{"post":{"description":"Returns the broker's open support ticket, creating one when none exists. The panel calls this on the first send after a closed ticket or for a brand-new broker.","operationId":"SupportController_openBrokerOwnSupportChat_v1","parameters":[],"responses":{"201":{"description":"The open support chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Open a support ticket for the broker (ScaleConnect)","tags":["Support"]}}}}
```

## List the broker's support tickets (ScaleConnect history)

> Open ticket first, then closed tickets most recent first. Each row carries first/last message previews and a message count for the History view.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportTicketHistoryResponseDto":{"type":"object","properties":{"chats":{"type":"array","items":{"$ref":"#/components/schemas/SupportTicketSummaryDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["chats","total","page","limit","totalPages"]},"SupportTicketSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]},"lastMessageAt":{"type":"string","format":"date-time"},"messageCount":{"type":"number"},"firstMessage":{"type":"string"},"lastMessage":{"type":"string"}},"required":["id","isActive","createdAt","messageCount"]}}},"paths":{"/v1/support/broker/my-support-chats":{"get":{"description":"Open ticket first, then closed tickets most recent first. Each row carries first/last message previews and a message count for the History view.","operationId":"SupportController_listBrokerOwnSupportChats_v1","parameters":[{"name":"limit","required":false,"in":"query","schema":{}},{"name":"page","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportTicketHistoryResponseDto"}}}}},"summary":"List the broker's support tickets (ScaleConnect history)","tags":["Support"]}}}}
```

## Close a support ticket

> The thread owner (broker in ScaleConnect) or staff closes the conversation. Appends a system line, flips is\_active, records closed\_at/closed\_by, emits \`chat\_closed\` to the chat room and to staff.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/{chatId}/close":{"post":{"description":"The thread owner (broker in ScaleConnect) or staff closes the conversation. Appends a system line, flips is_active, records closed_at/closed_by, emits `chat_closed` to the chat room and to staff.","operationId":"SupportController_closeSupportChat_v1","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Close a support ticket","tags":["Support"]}}}}
```

## Reopen a closed support ticket

> Staff may always reopen. The owner may reopen only when they have no other open ticket. Emits \`chat\_reopened\`.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/{chatId}/reopen":{"post":{"description":"Staff may always reopen. The owner may reopen only when they have no other open ticket. Emits `chat_reopened`.","operationId":"SupportController_reopenSupportChat_v1","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Reopen a closed support ticket","tags":["Support"]}}}}
```

## Get a signed upload URL for an image or video

> Validates type (jpeg/png/gif/webp/heic ≤ 10 MB; mp4/mov/webm ≤ 100 MB) and returns \`{ key, uploadUrl }\`. PUT the bytes to \`uploadUrl\` with the file's Content-Type, then include \`{ key, name, mimeType, sizeBytes }\` in \`attachments\` on the send. Keys are scoped to the chat.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"PresignAttachmentDto":{"type":"object","properties":{"name":{"type":"string"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"}},"required":["name","mimeType","sizeBytes"]}}},"paths":{"/v1/support/{chatId}/attachments/presign":{"post":{"description":"Validates type (jpeg/png/gif/webp/heic ≤ 10 MB; mp4/mov/webm ≤ 100 MB) and returns `{ key, uploadUrl }`. PUT the bytes to `uploadUrl` with the file's Content-Type, then include `{ key, name, mimeType, sizeBytes }` in `attachments` on the send. Keys are scoped to the chat.","operationId":"SupportController_presignAttachment_v1","parameters":[{"name":"chatId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignAttachmentDto"}}}},"responses":{"201":{"description":"{ key, uploadUrl, token }"}},"summary":"Get a signed upload URL for an image or video","tags":["Support"]}}}}
```

## Assign broker to user

> Triggered when client want to chat with and he selects a broker from broker list. Creates dedicated broker-client chat and establishes broker-client relationship.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/broker/assign":{"post":{"description":"Triggered when client want to chat with and he selects a broker from broker list. Creates dedicated broker-client chat and establishes broker-client relationship.","operationId":"SupportController_assignBroker_v1","parameters":[{"name":"brokerId","required":true,"in":"query","description":"Selected broker's user ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Broker chat created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Assign broker to user","tags":["Support"]}}}}
```

## Get user's broker chat

> This endpoint is for mobile so that client's broker chat can be loaded. returns broker-client chat if assigned.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/my-broker-chat":{"get":{"description":"This endpoint is for mobile so that client's broker chat can be loaded. returns broker-client chat if assigned.","operationId":"SupportController_getBrokerMyChat_v1","parameters":[],"responses":{"200":{"description":"Broker chat details with broker info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Get user's broker chat","tags":["Support"]}}}}
```

## List all chats (admin)

> Powers the admin chat list view. Returns paginated list of all chats (both support and broker) with unread counts for sorting/filtering.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ChatListResponseDto":{"type":"object","properties":{"chats":{"description":"Array of chat objects","type":"array","items":{"$ref":"#/components/schemas/SupportResponseDto"}},"total":{"type":"number","description":"Total number of chats"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["chats","total","page","limit","totalPages"]},"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/admin/chats":{"get":{"description":"Powers the admin chat list view. Returns paginated list of all chats (both support and broker) with unread counts for sorting/filtering.","operationId":"SupportController_getAllChats_v1","parameters":[{"name":"limit","required":false,"in":"query","description":"Chats per page","schema":{}},{"name":"page","required":false,"in":"query","description":"Page number for pagination","schema":{}}],"responses":{"200":{"description":"Paginated chat list with totals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatListResponseDto"}}}}},"summary":"List all chats (admin)","tags":["Support"]}}}}
```

## List support chats

> This endpoint is for admin to load the support chat list view. Returns paginated list of support-only chats with unread counts for sorting/filtering.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ChatListResponseDto":{"type":"object","properties":{"chats":{"description":"Array of chat objects","type":"array","items":{"$ref":"#/components/schemas/SupportResponseDto"}},"total":{"type":"number","description":"Total number of chats"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["chats","total","page","limit","totalPages"]},"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/admin/support-chats":{"get":{"description":"This endpoint is for admin to load the support chat list view. Returns paginated list of support-only chats with unread counts for sorting/filtering.","operationId":"SupportController_getAllSupportChats_v1","parameters":[{"name":"status","required":false,"in":"query","description":"Ticket status filter. Default all.","schema":{"enum":["open","closed","all"],"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{}}],"responses":{"200":{"description":"Paginated support-only chat list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatListResponseDto"}}}}},"summary":"List support chats","tags":["Support"]}}}}
```

## List available brokers

> This endpoint is for mobile broker selection screen so that client can select a broker to be linked with. returns list of available brokers.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"BrokerListResponseDto":{"type":"object","properties":{"brokers":{"description":"Array of broker profiles","type":"array","items":{"type":"object"}}},"required":["brokers"]}}},"paths":{"/v1/support/brokers":{"get":{"description":"This endpoint is for mobile broker selection screen so that client can select a broker to be linked with. returns list of available brokers.","operationId":"SupportController_getBrokers_v1","parameters":[],"responses":{"200":{"description":"List of broker profiles with contact details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrokerListResponseDto"}}}}},"summary":"List available brokers","tags":["Support"]}}}}
```

## List broker-client chats (admin)

> This endpoint is for admin to load the broker-client chat list view. Returns paginated list of broker-client chats with unread counts for sorting/filtering.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"ChatListResponseDto":{"type":"object","properties":{"chats":{"description":"Array of chat objects","type":"array","items":{"$ref":"#/components/schemas/SupportResponseDto"}},"total":{"type":"number","description":"Total number of chats"},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"totalPages":{"type":"number","description":"Total number of pages"}},"required":["chats","total","page","limit","totalPages"]},"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/admin/client-chats":{"get":{"description":"This endpoint is for admin to load the broker-client chat list view. Returns paginated list of broker-client chats with unread counts for sorting/filtering.","operationId":"SupportController_getAllClientChats_v1","parameters":[{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{}}],"responses":{"200":{"description":"Paginated broker chat list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatListResponseDto"}}}}},"summary":"List broker-client chats (admin)","tags":["Support"]}}}}
```

## List broker's client sessions

> Returns a lightweight list of the broker's client chats — client name, last message (with its sender), and unread count only.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}}},"paths":{"/v1/support/broker/sessions":{"get":{"description":"Returns a lightweight list of the broker's client chats — client name, last message (with its sender), and unread count only.","operationId":"SupportController_getBrokerChatSessions_v1","parameters":[],"responses":{"200":{"description":"Broker client session list"}},"summary":"List broker's client sessions","tags":["Support"]}}}}
```

## Get chat message history

> Loads messages for a specific selected chat. Returns paginated message history with sender info, timestamps, and read status for rendering conversation.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"MessageListResponseDto":{"type":"object","properties":{"data":{"description":"Array of messages","type":"array","items":{"$ref":"#/components/schemas/MessageDto"}},"page":{"type":"number","description":"Current page number"},"limit":{"type":"number","description":"Items per page"},"total":{"type":"number","description":"Total message count"}},"required":["data","page","limit","total"]},"MessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message unique identifier"},"chatId":{"type":"string","description":"Chat this message belongs to"},"content":{"type":"string","description":"Message text content"},"senderId":{"type":"string","description":"ID of user who sent the message"},"senderType":{"type":"string","description":"Type of sender (user or admin)","enum":["user","admin"]},"isRead":{"type":"boolean","description":"Whether message has been read"},"createdAt":{"type":"string","description":"Message creation timestamp","format":"date-time"},"attachments":{"description":"Images/video on the message. `url` is a signed read URL valid 24 h, minted on every read.","type":"array","items":{"type":"string"}}},"required":["id","chatId","content","senderId","senderType","isRead","createdAt"]}}},"paths":{"/v1/support/{chatId}/messages":{"get":{"description":"Loads messages for a specific selected chat. Returns paginated message history with sender info, timestamps, and read status for rendering conversation.","operationId":"SupportController_getChatMessages_v1","parameters":[{"name":"chatId","required":true,"in":"path","description":"Chat ID to fetch messages from","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Messages per page","schema":{}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{}}],"responses":{"200":{"description":"Paginated message list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageListResponseDto"}}}}},"summary":"Get chat message history","tags":["Support"]}}}}
```

## Send message as user

> This endpoint was previously used to send message from client side. Now replaced by WebSocket gateway. Creates message with user sender type, emits to admin, and notifies if admin offline.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateMessageDto":{"type":"object","properties":{"content":{"type":"string","description":"Message text. May be empty when at least one attachment is present."},"receiverId":{"type":"string","description":"Optional recipient ID for directed messages"},"attachments":{"description":"Images/video already uploaded through :chatId/attachments/presign","type":"array","items":{"$ref":"#/components/schemas/MessageAttachmentDto"}}}},"MessageAttachmentDto":{"type":"object","properties":{"key":{"type":"string","description":"Object key returned by POST :chatId/attachments/presign (support/<chatId>/…)"},"name":{"type":"string","description":"Original file name shown to the reader"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"},"durationMs":{"type":"number"}},"required":["key","name","mimeType","sizeBytes"]},"MessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message unique identifier"},"chatId":{"type":"string","description":"Chat this message belongs to"},"content":{"type":"string","description":"Message text content"},"senderId":{"type":"string","description":"ID of user who sent the message"},"senderType":{"type":"string","description":"Type of sender (user or admin)","enum":["user","admin"]},"isRead":{"type":"boolean","description":"Whether message has been read"},"createdAt":{"type":"string","description":"Message creation timestamp","format":"date-time"},"attachments":{"description":"Images/video on the message. `url` is a signed read URL valid 24 h, minted on every read.","type":"array","items":{"type":"string"}}},"required":["id","chatId","content","senderId","senderType","isRead","createdAt"]}}},"paths":{"/v1/support/{chatId}/messages":{"post":{"description":"This endpoint was previously used to send message from client side. Now replaced by WebSocket gateway. Creates message with user sender type, emits to admin, and notifies if admin offline.","operationId":"SupportController_createMessage_v1","parameters":[{"name":"chatId","required":true,"in":"path","description":"Chat ID to send message to","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"}}}},"responses":{"201":{"description":"Message created and sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDto"}}}}},"summary":"Send message as user","tags":["Support"]}}}}
```

## Send message as admin/broker

> This endpoints was previous used when admin/broker sends message in chat. Creates message with admin sender type, emits to client, and notifies if client offline.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateMessageDto":{"type":"object","properties":{"content":{"type":"string","description":"Message text. May be empty when at least one attachment is present."},"receiverId":{"type":"string","description":"Optional recipient ID for directed messages"},"attachments":{"description":"Images/video already uploaded through :chatId/attachments/presign","type":"array","items":{"$ref":"#/components/schemas/MessageAttachmentDto"}}}},"MessageAttachmentDto":{"type":"object","properties":{"key":{"type":"string","description":"Object key returned by POST :chatId/attachments/presign (support/<chatId>/…)"},"name":{"type":"string","description":"Original file name shown to the reader"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"},"durationMs":{"type":"number"}},"required":["key","name","mimeType","sizeBytes"]},"MessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message unique identifier"},"chatId":{"type":"string","description":"Chat this message belongs to"},"content":{"type":"string","description":"Message text content"},"senderId":{"type":"string","description":"ID of user who sent the message"},"senderType":{"type":"string","description":"Type of sender (user or admin)","enum":["user","admin"]},"isRead":{"type":"boolean","description":"Whether message has been read"},"createdAt":{"type":"string","description":"Message creation timestamp","format":"date-time"},"attachments":{"description":"Images/video on the message. `url` is a signed read URL valid 24 h, minted on every read.","type":"array","items":{"type":"string"}}},"required":["id","chatId","content","senderId","senderType","isRead","createdAt"]}}},"paths":{"/v1/support/admin/{chatId}/messages":{"post":{"description":"This endpoints was previous used when admin/broker sends message in chat. Creates message with admin sender type, emits to client, and notifies if client offline.","operationId":"SupportController_createAdminMessage_v1","parameters":[{"name":"chatId","required":true,"in":"path","description":"Chat ID to send message to","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"}}}},"responses":{"201":{"description":"Admin message created and sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDto"}}}}},"summary":"Send message as admin/broker","tags":["Support"]}}}}
```

## Send message as agent

> Creates message with agent sender type, emits to client, and notifies if client offline.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"CreateMessageDto":{"type":"object","properties":{"content":{"type":"string","description":"Message text. May be empty when at least one attachment is present."},"receiverId":{"type":"string","description":"Optional recipient ID for directed messages"},"attachments":{"description":"Images/video already uploaded through :chatId/attachments/presign","type":"array","items":{"$ref":"#/components/schemas/MessageAttachmentDto"}}}},"MessageAttachmentDto":{"type":"object","properties":{"key":{"type":"string","description":"Object key returned by POST :chatId/attachments/presign (support/<chatId>/…)"},"name":{"type":"string","description":"Original file name shown to the reader"},"mimeType":{"type":"string"},"sizeBytes":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"},"durationMs":{"type":"number"}},"required":["key","name","mimeType","sizeBytes"]},"MessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message unique identifier"},"chatId":{"type":"string","description":"Chat this message belongs to"},"content":{"type":"string","description":"Message text content"},"senderId":{"type":"string","description":"ID of user who sent the message"},"senderType":{"type":"string","description":"Type of sender (user or admin)","enum":["user","admin"]},"isRead":{"type":"boolean","description":"Whether message has been read"},"createdAt":{"type":"string","description":"Message creation timestamp","format":"date-time"},"attachments":{"description":"Images/video on the message. `url` is a signed read URL valid 24 h, minted on every read.","type":"array","items":{"type":"string"}}},"required":["id","chatId","content","senderId","senderType","isRead","createdAt"]}}},"paths":{"/v1/support/agent/{chatId}/messages":{"post":{"description":"Creates message with agent sender type, emits to client, and notifies if client offline.","operationId":"SupportController_createAgentMessage_v1","parameters":[{"name":"chatId","required":true,"in":"path","description":"Chat ID to send message to","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"}}}},"responses":{"201":{"description":"Agent message created and sent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageDto"}}}}},"summary":"Send message as agent","tags":["Support"]}}}}
```

## Mark messages as read

> Called when user opens/views chat. Marks all messages in chat as read and resets unread badge count in UI.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportSuccessResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Operation success status"}},"required":["success"]}}},"paths":{"/v1/support/{chatId}/read":{"post":{"description":"Called when user opens/views chat. Marks all messages in chat as read and resets unread badge count in UI.","operationId":"SupportController_markMessagesAsRead_v1","parameters":[{"name":"chatId","required":true,"in":"path","description":"Chat ID to mark as read","schema":{"type":"string"}}],"responses":{"200":{"description":"Messages marked as read","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportSuccessResponseDto"}}}}},"summary":"Mark messages as read","tags":["Support"]}}}}
```

## Get support chat with user (broker | admin)

> Loads selected user's support chat in broker's client manager and admin panel. Returns Scale support chat only.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/admin/{userId}/support-chat":{"get":{"description":"Loads selected user's support chat in broker's client manager and admin panel. Returns Scale support chat only.","operationId":"SupportController_getSupportChatWithUser_v1","parameters":[{"name":"userId","required":true,"in":"path","description":"User ID to get support chat for","schema":{"type":"string"}}],"responses":{"200":{"description":"User's support chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Get support chat with user (broker | admin)","tags":["Support"]}}}}
```

## Get or create broker chat (broker | admin)

> Loads selected user's broker chat in broker's client manager and admin panel. Auto-creates broker chat if doesn't exist. Used by admins managing broker relationships.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Unique chat identifier for routing and WebSocket subscriptions"},"userId":{"type":"string","description":"User ID who owns this chat"},"supportChat":{"type":"boolean","description":"Distinguishes Scale support (true) from broker chat (false). Used for UI routing and filtering."},"unreadCount":{"type":"number","description":"Unread message count for displaying notification badge"},"brokerName":{"type":"string","description":"Broker's business name, shown in chat header when broker assigned"},"brokerTradingName":{"type":"string","description":"Broker's trading name for secondary display in broker card"},"brokerImageUrl":{"type":"string","description":"Broker's avatar URL for displaying profile picture in chat"},"brokerSupabaseId":{"type":"string","description":"Broker's Supabase user id; matches `broker-connections` disconnect path param"},"createdAt":{"type":"string","description":"Chat creation timestamp","format":"date-time"},"updatedAt":{"type":"string","description":"Last activity timestamp, used for sorting chat list by recency","format":"date-time"},"userKind":{"type":"string","description":"Who owns the thread: a mobile client or a ScaleConnect broker. Brokers are named from their broker profile because their user row has no personal details.","enum":["client","broker"]},"userTradingName":{"type":"string","description":"Owner's trading name when the owner is a broker"},"isActive":{"type":"boolean","description":"Tickets: true while the conversation is open. Support chats flip to false when closed by the owner or by staff."},"closedAt":{"type":"string","format":"date-time"},"closedBy":{"type":"string","enum":["user","admin"]}},"required":["id","userId","supportChat","unreadCount","createdAt","updatedAt","userKind","isActive"]}}},"paths":{"/v1/support/admin/{userId}/client-chat":{"get":{"description":"Loads selected user's broker chat in broker's client manager and admin panel. Auto-creates broker chat if doesn't exist. Used by admins managing broker relationships.","operationId":"SupportController_getOrCreateBrokerChatWithUser_v1","parameters":[{"name":"userId","required":true,"in":"path","description":"User ID to get/create broker chat for","schema":{"type":"string"}}],"responses":{"200":{"description":"Broker chat details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportResponseDto"}}}}},"summary":"Get or create broker chat (broker | admin)","tags":["Support"]}}}}
```

## Claim support chat (admin)

> Assigns admin as handler for support chat, used for workload distribution.

```json
{"openapi":"3.0.0","info":{"title":"ScaleApp API","version":"1.0.0"},"tags":[{"name":"Support","description":"Support ticket system and help desk"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"SupportSuccessResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Operation success status"}},"required":["success"]}}},"paths":{"/v1/support/admin/{supportId}/assign":{"post":{"description":"Assigns admin as handler for support chat, used for workload distribution.","operationId":"SupportController_assignAdminToChat_v1","parameters":[{"name":"supportId","required":true,"in":"path","description":"Support chat ID to claim","schema":{"type":"string"}}],"responses":{"200":{"description":"Admin assigned to chat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportSuccessResponseDto"}}}}},"summary":"Claim support chat (admin)","tags":["Support"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.scaleconnect.com.au/api/rest-api/scaleapp-rest-api/support.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
