From 07b445e92ddc6d6f88e707881e0bfdfee7d48ef0 Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Tue, 12 May 2026 06:03:26 +0530 Subject: [PATCH] docs(sessions): document GET/POST /api/sessions/{sessionId}/chats Adds OpenAPI paths + schemas (ChatSummary, ListSessionChatsResponse, CreateSessionChatRequest/Response, parity errors) and two MDX pages, plus nav entries under the Sessions group. Co-Authored-By: Claude Opus 4.7 (1M context) --- api-reference/openapi/sessions.json | 279 +++++++++++++++++++++++++ api-reference/sessions/create-chat.mdx | 4 + api-reference/sessions/list-chats.mdx | 4 + docs.json | 4 +- 4 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 api-reference/sessions/create-chat.mdx create mode 100644 api-reference/sessions/list-chats.mdx diff --git a/api-reference/openapi/sessions.json b/api-reference/openapi/sessions.json index 350f8f8..3b9fe1c 100644 --- a/api-reference/openapi/sessions.json +++ b/api-reference/openapi/sessions.json @@ -138,6 +138,162 @@ } } } + }, + "/api/sessions/{sessionId}/chats": { + "get": { + "summary": "List session chats", + "description": "Lists every chat in the given session as a `ChatSummary` (chat row plus per-account `hasUnread` and `isStreaming` flags), along with the caller's default model id. Chats are sorted by `createdAt` ascending.", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "The id of the parent session.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Chats retrieved successfully.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListSessionChatsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized — invalid or missing API key / Bearer token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden — the authenticated account does not own this session.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Not found — no session exists with the given id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "summary": "Create session chat", + "description": "Creates a new chat inside the given session. Callers may pass `{ id }` to claim a deterministic chat id — useful for optimistic UI flows where the client generates the id locally and then persists it. If a chat with that id already exists in **this** session the call is idempotent and returns the existing row; if it exists in **another** session, 409 is returned.", + "parameters": [ + { + "name": "sessionId", + "in": "path", + "required": true, + "description": "The id of the parent session.", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSessionChatRequest" + } + } + } + }, + "responses": { + "200": { + "description": "Chat created, or existing chat returned (idempotent on same-session reuse).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSessionChatResponse" + } + } + } + }, + "400": { + "description": "Invalid chat id — body contained `id` but it was an empty string or not a string.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InvalidChatIdError" + } + } + } + }, + "401": { + "description": "Unauthorized — invalid or missing API key / Bearer token.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "Forbidden — the authenticated account does not own this session.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "Not found — no session exists with the given id.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Chat id conflict — a chat with the requested id already exists on a different session.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ChatIdConflictError" + } + } + } + }, + "500": { + "description": "Server error — the chat could not be persisted.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } } }, "components": { @@ -264,6 +420,129 @@ } } }, + "ChatSummary": { + "type": "object", + "description": "Chat row enriched with per-account `hasUnread` and computed `isStreaming` flags for chat-list rendering.", + "required": [ + "id", + "sessionId", + "title", + "createdAt", + "updatedAt", + "hasUnread", + "isStreaming" + ], + "properties": { + "id": { + "type": "string" + }, + "sessionId": { + "type": "string" + }, + "title": { + "type": "string" + }, + "modelId": { + "type": "string", + "nullable": true + }, + "activeStreamId": { + "type": "string", + "nullable": true + }, + "lastAssistantMessageAt": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + }, + "hasUnread": { + "type": "boolean", + "description": "True when `lastAssistantMessageAt` is newer than the caller's `chat_reads.last_read_at` (or no read row exists yet)." + }, + "isStreaming": { + "type": "boolean", + "description": "True when `activeStreamId` is non-null." + } + } + }, + "ListSessionChatsResponse": { + "type": "object", + "required": [ + "chats", + "defaultModelId" + ], + "properties": { + "chats": { + "type": "array", + "description": "Every chat in the session, sorted by `createdAt` ascending.", + "items": { + "$ref": "#/components/schemas/ChatSummary" + } + }, + "defaultModelId": { + "type": "string", + "description": "Default model id surfaced to clients with no explicit preference (e.g. `openai/gpt-5.4`)." + } + } + }, + "CreateSessionChatRequest": { + "type": "object", + "description": "Body for `POST /api/sessions/{sessionId}/chats`. Both an empty body and an omitted body are valid.", + "properties": { + "id": { + "type": "string", + "minLength": 1, + "description": "Optional client-supplied chat id (used for optimistic UI flows). When omitted, the server generates a UUID. When supplied, must be a non-empty string." + } + } + }, + "CreateSessionChatResponse": { + "type": "object", + "required": [ + "chat" + ], + "properties": { + "chat": { + "$ref": "#/components/schemas/Chat" + } + } + }, + "InvalidChatIdError": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string", + "enum": [ + "Invalid chat id" + ] + } + } + }, + "ChatIdConflictError": { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string", + "enum": [ + "Chat ID conflict" + ] + } + } + }, "Session": { "type": "object", "required": [ diff --git a/api-reference/sessions/create-chat.mdx b/api-reference/sessions/create-chat.mdx new file mode 100644 index 0000000..9dfc7b8 --- /dev/null +++ b/api-reference/sessions/create-chat.mdx @@ -0,0 +1,4 @@ +--- +title: "Create Session Chat" +openapi: "/api-reference/openapi/sessions.json POST /api/sessions/{sessionId}/chats" +--- diff --git a/api-reference/sessions/list-chats.mdx b/api-reference/sessions/list-chats.mdx new file mode 100644 index 0000000..dc4a2a3 --- /dev/null +++ b/api-reference/sessions/list-chats.mdx @@ -0,0 +1,4 @@ +--- +title: "List Session Chats" +openapi: "/api-reference/openapi/sessions.json GET /api/sessions/{sessionId}/chats" +--- diff --git a/docs.json b/docs.json index e430c00..31da86f 100644 --- a/docs.json +++ b/docs.json @@ -286,7 +286,9 @@ "group": "Sessions", "pages": [ "api-reference/sessions/create", - "api-reference/sessions/get" + "api-reference/sessions/get", + "api-reference/sessions/list-chats", + "api-reference/sessions/create-chat" ] }, {