Support Tickets
Overview
Support tickets let a Client (workspace owner) raise issues or suggestions with the platform team as a threaded conversation. A ticket has a subject, a category (issue · suggestion · billing · other), a status (open · in_progress · resolved), and a list of messages from both sides.
These endpoints are for the Clientside only. Each client sees only its own tickets - every query is scoped to the caller's clientId. Tickets live in the root DB.
Auth & headers
All support routes require a Client Bearer token (the isClient token). Send tenant headers so the middleware resolves the caller.
Create ticket
{baseUrl}/api/{apiVersion}/support/tickets- Authentication
- Required (Client Bearer token)
Opens a ticket with the first message. Required: subject, message. Optional: category (defaults to issue).
{ "subject": "Unable to log in", "category": "issue", "message": "It says \"Invalid email or password\"."}Response (HTTP 201)
{ "success": true, "message": "Ticket created successfully", "data": { "_id": "6a5f...c17d", "clientId": "699fe1377846dcfb775c645c", "subject": "Unable to log in", "category": "issue", "status": "open", "messages": [ { "_id": "6a5f...c17e", "authorType": "client", "authorName": "Client Pro 1", "body": "It says \"Invalid email or password\".", "createdAt": "2026-07-21T09:04:09.578Z" } ], "clientUnread": false, "lastMessageAt": "2026-07-21T09:04:09.578Z", "createdAt": "2026-07-21T09:04:09.578Z" }, "error": null}List my tickets
{baseUrl}/api/{apiVersion}/support/tickets?page=1&limit=10&status=open- Authentication
- Required (Client Bearer token)
Lists the client's own tickets, newest-first. Query params: page (default 1), limit (default 20, max 50), status (optional filter).
{ "success": true, "message": "Tickets fetched successfully", "data": { "list": [ { "_id": "6a5f...c17d", "subject": "Unable to log in", "category": "issue", "status": "in_progress", "clientUnread": true, "lastMessageAt": "2026-07-21T09:12:00.000Z", "createdAt": "2026-07-21T09:04:09.578Z" } ], "pagination": { "currentPage": 1, "totalCount": 1, "pageSize": 10, "hasNextPage": false, "hasPreviousPage": false } }, "error": null}Get ticket
{baseUrl}/api/{apiVersion}/support/tickets/{ticketId}- Authentication
- Required (Client Bearer token)
Returns the full ticket with its messages thread. Reading a ticket clears its unread flagfor the client (so the nav badge decrements). A 404 is returned for a ticket that isn't the caller's.
Reply to a ticket
{baseUrl}/api/{apiVersion}/support/tickets/{ticketId}/reply- Authentication
- Required (Client Bearer token)
Appends a message. Body: { "message": "…" }. Replying to a resolved ticket re-opens it. Returns the updated ticket.
Unread count
{baseUrl}/api/{apiVersion}/support/unread-count- Authentication
- Required (Client Bearer token)
Returns { "count": <number> }- the number of the client's tickets with an unread reply from the support team. Drives the sidebar badge.
Stats
{baseUrl}/api/{apiVersion}/support/stats- Authentication
- Required (Client Bearer token)
Per-status counts for the client's tickets, in one call - powers the summary tiles.
{ "success": true, "message": "Support stats fetched successfully", "data": { "open": 0, "in_progress": 1, "resolved": 1, "total": 2 }, "error": null}Realtime
Live updates ride the dedicated /support Socket.IO namespace (path /connection). Connect with the client token, join a ticket room, and listen for support_message_receive, support_status_receive, support_typing_receive, and support_queue_update. REST is the source of truth; the socket only reflects changes instantly, so the feature degrades to polling if the socket drops.
Common Errors
Best Practices
- Use Statsfor the summary tiles instead of counting the list client-side - it's one query.
- Poll Unread count for the badge, and refresh it live on the
support_queue_updatesocket event. - After sending a reply, append the returned message inline rather than refetching the whole list.
- Always send tenant headers with the client Bearer token over HTTPS.
Support inbox ready
Wire these into a client-facing support screen: list tickets, open a thread, reply, and badge unread - with the /support socket for live updates.