openapi: 3.2.0 info: title: Pipeshub Conversations API version: 1.0.0 contact: name: API Support email: support@pipeshub.com description: 'Operations tagged Conversations across 2 of this provider''s published API definitions: pipeshub-openapi.yaml, pipeshub-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL security: - bearerAuth: [] - oauth2: [] tags: - name: Conversations description: AI-powered conversational chat management with citations and follow-up questions paths: /conversations/create: post: tags: - Conversations summary: Create conversation (non-streaming) description: 'Start a new assistant conversation and wait for the complete answer. The JSON counterpart of `POST /conversations/stream`, for API, SDK and automation callers that do not consume SSE. **How a turn runs** 1. The user''s message is saved (in its own short transaction on a replica set). 2. The AI backend runs the same agent-loop pipeline as the `/stream` route and returns only its final result. No transaction is held during this call, and the call is never retried. 3. The answer, citations and status are saved exactly as the streaming route saves them, and the updated conversation is returned. Every failure after step 1 is persisted: the conversation ends with status `Failed`, a `failReason`, and an `error` message, and the response carries `X-Conversation-Id` so the caller can fetch it. A 4xx from the AI backend (for example no model configured) keeps its status and user-facing message; other failures return 500 with a generic message. The response arrives only when the whole answer is ready, which can take minutes for agent runs. Allow a generous client and proxy timeout, or use the `/stream` variant for interactive clients. **Modes** `chatMode: agent` (or `agent:`) runs the universal agent and honours `tools` / `agentCapabilities`; `internal_search` and `web_search` run the search assistant and ignore `tools`. Omitted, it defaults to internal search.' operationId: createConversation x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write requestBody: required: true description: The first question, with optional scope, model and mode. content: application/json: schema: $ref: '#/components/schemas/CreateConversationRequest' responses: '201': description: Conversation created with its first answer. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/CreateConversationResponse' '400': description: 'Invalid request — `query` is missing or empty, contains markup or printf-style format specifiers, or another field fails validation. ' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized — valid bearer token required. '403': description: Forbidden — the token lacks the `conversation:write` OAuth scope. '413': description: The request is larger than the selected model accepts. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '422': description: The model provider's content filter blocked the request. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '424': description: 'No usable LLM — none is configured for the organization, or the selected one could not start. The message says what to fix. ' headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': description: The model provider is rate limiting or out of quota. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '500': description: 'The answer failed (AI service unreachable, timed out, returned no answer, or could not be saved). The conversation is kept with status `Failed` and an `error` message. ' headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/stream: post: tags: - Conversations summary: Create conversation with streaming response description: 'Start a new conversation and stream the AI response over Server-Sent Events (SSE). Behaves like `POST /conversations` but emits tokens, tool activity, and status updates incrementally instead of returning a single JSON response at the end. **Lifecycle** 1. The server validates `query`, persists an in-progress conversation, then opens the SSE stream with HTTP `200`. 2. A `CUSTOM` event named `conversation_created` is emitted immediately with the new `conversationId` so the client can link the stream (sidebar, parallel tabs, deep links) without an extra request. 3. AI-backend events stream through (token chunks, tool calls, status, etc.). 4. On success a single root `RUN_FINISHED` event is emitted carrying the full persisted conversation in `result`. 5. On failure a root `RUN_ERROR` event is emitted and the conversation is marked FAILED before the stream closes. **Event vocabulary** AG-UI is the sole wire protocol. See `ConversationStreamSSEEvent` for the full event enum and payload guidance. Clients should ignore unknown event names rather than treating them as errors. **Agent mode** When `chatMode` is `agent`, the optional `tools` list restricts which tools the agent may invoke for this turn. Outside agent modes the `tools` field is ignored.' operationId: streamChat x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:chat requestBody: required: true description: Request payload content: application/json: schema: $ref: '#/components/schemas/ConversationStreamRequest' responses: '200': description: 'SSE stream established. The body is a sequence of `text/event-stream` frames using the event vocabulary described above. ' content: text/event-stream: schema: $ref: '#/components/schemas/ConversationStreamSSEEvent' '400': description: 'Invalid request — `query` is missing, empty, or exceeds the 100000-character limit, or another field fails validation (for example a malformed `recordIds` or `currentTime`). ' '401': description: Unauthorized — valid bearer token required. '403': description: 'Forbidden — the caller''s token does not include the `conversation:chat` OAuth scope. ' '500': description: 'Internal error before the SSE stream is established (for example, the initial conversation row could not be persisted). Once the stream is open, terminal failures are surfaced as a `RUN_ERROR` SSE event instead of an HTTP status change. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/attachments/upload: post: tags: - Conversations summary: Upload chat attachments (assistant) description: 'Multipart upload of **PDF**, **JPEG**, or **PNG** files for the assistant chat UI. The gateway validates MIME types (only those three), then forwards a JSON payload to the query service at `POST /api/v1/chat/attachments/upload`. **Multer** enforces at most **10** files and **5 MiB** per file (oversized requests fail before the handler runs). Form fields: required file part(s) named **`files`**; optional text field **`conversationId`** (existing thread id, or omit / leave empty for uploads not yet tied to a conversation).' operationId: uploadConversationChatAttachments security: - bearerAuth: [] - oauth2: - conversation:chat requestBody: required: true description: '`multipart/form-data` with part name `files` (one or more files) and optional `conversationId` text field. ' content: multipart/form-data: schema: type: object required: - files properties: conversationId: type: string pattern: ^$|^[0-9a-fA-F]{24}$ description: 'Optional existing conversation id. Empty string is treated as unset; any non-empty value must be a 24-character ObjectId. ' files: type: array minItems: 1 maxItems: 10 description: 'One or more files; part name must be `files`. Accepted MIME types: `application/pdf`, `image/jpeg`, `image/jpg`, `image/png`, `text/plain`, `text/markdown`, `text/mdx`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`, `text/csv`, `text/tab-separated-values`. Max 5 MiB each. ' items: type: string format: binary responses: '200': description: 'Success. The gateway proxies the AI-backend JSON envelope after transforming the multipart upload into the backend attachment payload. ' content: application/json: schema: $ref: '#/components/schemas/ChatAttachmentUploadResponse' '400': description: 'Invalid `conversationId`, no files, unsupported MIME type, or Multer rejection (e.g. file too large). ' '401': description: Unauthorized '403': description: Missing `conversation:chat` scope '500': description: 'Gateway fallback when the upstream call does not return a status (implementation default). ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/attachments/{recordId}: delete: tags: - Conversations summary: Delete a chat attachment (assistant) description: 'Deletes a previously uploaded attachment by proxying `DELETE` to the query service (`/api/v1/chat/attachments/{recordId}`). The Node handler always ends the response **without a JSON body** on success (empty body); the **status code** is the upstream status, or **204** if none is returned. On validation failure in the gateway (missing/blank `recordId`), the response is **400** with a small JSON error object.' operationId: deleteConversationChatAttachment security: - bearerAuth: [] - oauth2: - conversation:chat parameters: - name: recordId in: path required: true description: Attachment record id (from the upload response). Must be non-blank after trim. schema: type: string responses: '204': description: Success with no content (typical when upstream returns 204). '400': description: Missing or blank `recordId` after trim (gateway validation). content: application/json: schema: type: object additionalProperties: false required: - error properties: error: type: string example: recordId is required '401': description: Unauthorized '403': description: Missing `conversation:chat` scope default: description: 'Other status codes are forwarded from the query service (e.g. 404) with an **empty** response body from this route. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations: get: tags: - Conversations summary: List all conversations description: 'Retrieve paginated conversations for the authenticated user. **Overview:** Use the optional `source` query parameter to choose which list to return: `owned` — only conversations you own (`userId` matches the current user). `shared` — conversations where you have recipient access (`isShared` and your user appears in `sharedWith`), without the owner-only branch. Defaults to `owned` when omitted. Each call returns one list; call twice if you need both. **Filtering:** - Only non-archived conversations are returned by default - Use `/conversations/show/archives` for archived conversations **Sorting:** Conversations are sorted by last activity timestamp (most recent first) by default.' operationId: getAllConversations x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:read parameters: - name: source in: query required: false description: '`owned` — owner list (`userId` filter only). `shared` — explicit share grant list (`isShared` + `sharedWith`). Defaults to `owned` when omitted. ' schema: type: string enum: - owned - shared default: owned - name: page in: query required: false description: Page number (1-based). Defaults to 1. schema: type: integer minimum: 1 - name: limit in: query required: false description: Page size. Defaults to 20; capped by the server (max 100). schema: type: integer minimum: 1 - name: sortBy in: query required: false description: Sort field. Invalid values fall back to `lastActivityAt`. schema: type: string enum: - createdAt - lastActivityAt - title - name: sortOrder in: query required: false description: Sort direction. Defaults to `desc` unless set to `asc`. schema: type: string enum: - asc - desc - name: conversationId in: query required: false description: When set, restricts results to that conversation ID (if visible under the chosen `source`). schema: type: string - name: search in: query required: false description: Case-insensitive match on title and message content (max 1000 characters). schema: type: string - name: startDate in: query required: false description: Filter by `createdAt` ≥ this ISO date. schema: type: string format: date-time - name: endDate in: query required: false description: Filter by `createdAt` ≤ this ISO date. schema: type: string format: date-time - name: shared in: query required: false description: 'When set, filters by `isShared`. Accepts case-insensitive `true`/`false`, or `1`/`0`. ' schema: type: string - name: projectId in: query required: false description: 'Restrict results to a single project. Pass a project''s `id` to list conversations linked to that project (visible to the caller — owner, member, or org-visible project with `projectVisibility: project`), or the literal string `unassigned` to list conversations with no `projectId`. ' schema: type: string responses: '200': description: List of conversations for the requested source content: application/json: schema: type: object required: - conversations - source - pagination - filters - meta properties: conversations: type: array items: $ref: '#/components/schemas/ConversationListItem' source: type: string enum: - owned - shared description: Echoes the requested `source` query value. pagination: type: object properties: page: type: integer limit: type: integer totalCount: type: integer totalPages: type: integer hasNextPage: type: boolean hasPrevPage: type: boolean filters: type: object additionalProperties: false description: 'Filter introspection block. `applied` summarises the filters active on this request; `available` catalogues every supported filter with its current value and whether it is applied. ' required: - applied - available properties: applied: type: object additionalProperties: false required: - filters - values properties: filters: type: array description: Names of filters currently applied. items: type: string values: type: object additionalProperties: false description: 'Current value for each applied filter. Only keys present in `filters` are populated; others are omitted. ' properties: search: type: string shared: type: string tags: type: string minMessages: type: string sortBy: type: string sortOrder: type: string startDate: type: string endDate: type: string messageType: type: string page: type: integer limit: type: integer dateRange: type: object additionalProperties: false properties: start: type: - string - 'null' end: type: - string - 'null' available: type: object additionalProperties: false required: - shared - tags - minMessages - search - pagination - sorting - dateFilters - messageFilters - sortingMessages properties: shared: type: object additionalProperties: false properties: values: type: array items: type: string description: Accepted values for the `shared` query param. description: type: string current: type: - string - 'null' applied: type: boolean tags: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean minMessages: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - number - 'null' applied: type: boolean search: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean pagination: type: object additionalProperties: false properties: page: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean limit: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean sorting: type: object additionalProperties: false properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string applied: type: boolean sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string applied: type: boolean dateFilters: type: object additionalProperties: false properties: dateRange: type: object additionalProperties: false properties: type: type: string description: type: string format: type: string current: type: object additionalProperties: false properties: start: type: - string - 'null' end: type: - string - 'null' applied: type: boolean messageFilters: type: object additionalProperties: false properties: messageType: type: object additionalProperties: false properties: values: type: array items: type: string description: type: string current: type: - string - 'null' applied: type: boolean sortingMessages: type: object additionalProperties: false properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string meta: type: object properties: requestId: type: string timestamp: type: string format: date-time duration: type: integer '400': description: 'Bad request — for example, missing or invalid `source` (must be `owned` or `shared`), invalid date query params, invalid `search` shape, or search text over the length limit. ' '401': description: Unauthorized - Valid bearer token required servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/show/archives: get: tags: - Conversations summary: List archived conversations description: 'Retrieve all archived conversations for the authenticated user. **Overview:** Archived conversations are hidden from the main list but preserved for reference. This endpoint returns only conversations where `isArchived: true` and `archivedBy` is set. Results include conversations the caller owns and those shared with them. **Filtering and sorting:** Results can be narrowed using `search`, `shared`, `startDate`, `endDate`, and `conversationId`. Sorting is controlled by `sortBy` and `sortOrder`. Pagination is controlled by `page` and `limit`. **Unarchiving:** Use `PATCH /conversations/{conversationId}/unarchive` to restore a conversation to the active list.' operationId: getArchivedConversations x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:read parameters: - name: page in: query required: false description: Page number (1-indexed) schema: type: integer minimum: 1 maximum: 1000 default: 1 - name: limit in: query required: false description: Items per page schema: type: integer minimum: 1 maximum: 100 default: 20 - name: sortBy in: query required: false description: Field to sort by schema: type: string enum: - createdAt - lastActivityAt - title default: lastActivityAt - name: sortOrder in: query required: false description: Sort direction schema: type: string enum: - asc - desc default: desc - name: search in: query required: false description: Case-insensitive substring match against title and message content (max 1000 chars) schema: type: string maxLength: 1000 - name: shared in: query required: false description: Filter by shared status schema: type: boolean - name: startDate in: query required: false description: Include conversations created on or after this timestamp schema: type: string format: date-time - name: endDate in: query required: false description: Include conversations created on or before this timestamp schema: type: string format: date-time - name: conversationId in: query required: false description: Restrict results to a single conversation by identifier schema: type: string format: objectId responses: '200': description: List of archived conversations content: application/json: schema: type: object additionalProperties: false properties: conversations: type: array description: Archived conversations matching the filter items: allOf: - $ref: '#/components/schemas/Conversation' - type: object properties: archivedAt: type: string format: date-time description: Timestamp when the conversation was archived pagination: type: object additionalProperties: false properties: page: type: integer description: Current page number limit: type: integer description: Items per page totalCount: type: integer description: Total archived conversations matching the filter totalPages: type: integer description: Total pages at the current limit hasNextPage: type: boolean description: Whether a next page exists hasPrevPage: type: boolean description: Whether a previous page exists filters: type: object additionalProperties: false description: Filters applied to this request and filters available for clients to use properties: applied: type: object additionalProperties: false properties: filters: type: array description: Names of filters that were applied items: type: string values: type: object additionalProperties: true description: Map of applied filter name to its current value available: type: object additionalProperties: false description: Describes filters supported by this endpoint and their current values properties: shared: type: object additionalProperties: false properties: values: type: array items: type: string description: Allowed values for the `shared` filter description: type: string current: type: - string - 'null' description: Current value supplied by the caller, or null applied: type: boolean description: Whether this filter was applied on the request tags: type: object additionalProperties: false properties: type: type: string description: Expected value type description: type: string current: type: - string - 'null' applied: type: boolean minMessages: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - integer - 'null' applied: type: boolean search: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean pagination: type: object additionalProperties: false properties: page: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean limit: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean sorting: type: object additionalProperties: false properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string applied: type: boolean sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string enum: - asc - desc default: type: string enum: - asc - desc description: type: string current: type: string enum: - asc - desc applied: type: boolean dateFilters: type: object additionalProperties: false properties: dateRange: type: object additionalProperties: false properties: type: type: string description: type: string format: type: string description: Expected date format for `startDate` and `endDate` inputs current: type: object additionalProperties: false properties: start: type: - string - 'null' format: date-time end: type: - string - 'null' format: date-time applied: type: boolean messageFilters: type: object additionalProperties: false properties: messageType: type: object additionalProperties: false properties: values: type: array items: type: string description: type: string current: type: - string - 'null' applied: type: boolean sortingMessages: type: object additionalProperties: false properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string enum: - asc - desc default: type: string enum: - asc - desc description: type: string current: type: string enum: - asc - desc summary: type: object additionalProperties: false properties: totalArchived: type: integer description: Total archived conversations matching the filter oldestArchive: type: string format: date-time description: Archive timestamp of the first item in the current page newestArchive: type: string format: date-time description: Archive timestamp of the last item in the current page meta: type: object additionalProperties: false properties: requestId: type: string description: Request correlation identifier timestamp: type: string format: date-time description: Response generation timestamp duration: type: integer description: Server processing time in milliseconds '401': description: Unauthorized servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/show/archives/search: get: tags: - Conversations summary: Search archived conversations description: 'Search across all archived conversations (assistant and agent) for the authenticated user. **Overview:** Performs a case-insensitive substring match against conversation titles and message content across both assistant (`Conversation`) and agent (`AgentConversation`) archived collections. Results are merged server-side and sorted by `lastActivityAt` descending. **Search parameter:** The `search` query parameter is required, must be a non-empty string, and is capped at 1000 characters. Requests that omit it or exceed the cap return `400`. **Pagination:** Results are paginated using `page` and `limit`. The response includes a `pagination` block with total counts and a `summary` block that breaks matches down by source. **Item shape:** Each item is a conversation list entry (no `messages` payload — that field is omitted for performance) tagged with `source`, plus computed `isOwner`, `accessLevel`, `archivedAt`, and `archivedBy`. `agentKey` is present only when `source` is `agent`.' operationId: searchArchivedConversations x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:read parameters: - name: search in: query required: true description: Search term to match against conversation titles and message content (max 1000 chars) schema: type: string minLength: 1 maxLength: 1000 - name: page in: query required: false description: Page number (1-indexed) schema: type: integer minimum: 1 maximum: 1000 default: 1 - name: limit in: query required: false description: Items per page schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Search results across archived conversations content: application/json: schema: type: object additionalProperties: false properties: conversations: type: array description: Archived conversations (assistant and agent) matching the search term items: allOf: - $ref: '#/components/schemas/ConversationListItem' - type: object properties: source: type: string enum: - assistant - agent description: Origin collection of the conversation agentKey: type: string description: Agent identifier — present only when `source` is `agent` archivedAt: type: string format: date-time description: Timestamp when the conversation was archived pagination: type: object additionalProperties: false properties: page: type: integer description: Current page number limit: type: integer description: Items per page totalCount: type: integer description: Total matches across assistant and agent archives totalPages: type: integer description: Total pages at the current limit hasNextPage: type: boolean description: Whether a next page exists hasPrevPage: type: boolean description: Whether a previous page exists summary: type: object additionalProperties: false properties: totalMatches: type: integer description: Combined match count across both collections assistantMatches: type: integer description: Match count in the assistant (`Conversation`) collection agentMatches: type: integer description: Match count in the agent (`AgentConversation`) collection searchQuery: type: string description: Trimmed search term that was applied meta: type: object additionalProperties: false properties: requestId: type: string description: Request correlation identifier timestamp: type: string format: date-time description: Response generation timestamp duration: type: integer description: Server processing time in milliseconds '400': description: Search parameter missing, empty, not a string, or longer than 1000 characters '401': description: Unauthorized servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}: get: tags: - Conversations summary: Get conversation by ID description: 'Retrieve a specific conversation with its full message history. **Overview:** Returns the complete conversation including all messages, citations, feedback, and metadata. Messages can be paginated for long conversations. **Message Pagination:** For conversations with many messages, use pagination parameters: - `page`: Page number (default: 1) - `limit`: Messages per page (default: 10) - `sortBy`: Sort field (default: createdAt) - `sortOrder`: ''asc'' or ''desc'' (default: desc) **Access Control:** Users can access conversations they own or that have been shared with them.' operationId: getConversationById x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:read parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId example: 507f1f77bcf86cd799439011 - name: page in: query description: Page number for message pagination schema: type: integer minimum: 1 default: 1 - name: limit in: query description: Number of messages per page schema: type: integer minimum: 1 maximum: 100 default: 20 - name: sortBy in: query description: Field to sort messages by schema: type: string enum: - createdAt - messageType - content default: createdAt - name: sortOrder in: query description: Sort direction schema: type: string enum: - asc - desc default: desc - name: search in: query description: Case-insensitive search across conversation title and message content schema: type: string maxLength: 1000 - name: startDate in: query description: Filter messages created on or after this date (ISO 8601) schema: type: string format: date-time - name: endDate in: query description: Filter messages created on or before this date (ISO 8601) schema: type: string format: date-time - name: shared in: query description: Filter by shared status of the conversation schema: type: boolean - name: messageType in: query description: Filter messages by type schema: type: string enum: - user_query - bot_response - error - feedback - system responses: '200': description: Conversation with paginated messages, applied filter metadata, and request metadata content: application/json: schema: type: object additionalProperties: false properties: conversation: type: object additionalProperties: false properties: id: type: string format: objectId description: Unique conversation identifier title: type: string description: Conversation title initiator: type: string format: objectId description: User who started the conversation createdAt: type: string format: date-time isShared: type: boolean sharedWith: type: array items: type: object additionalProperties: false properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write status: type: string enum: - None - Inprogress - Complete - Failed - Stopped failReason: type: string description: Populated only when `status` is `Failed` messages: type: array description: Page of messages, sliced by `pagination` and ordered by `sortingMessages` items: type: object additionalProperties: false properties: _id: type: string format: objectId messageType: type: string enum: - user_query - bot_response - error - feedback - system - tool_call content: type: string contentFormat: type: string enum: - MARKDOWN - JSON - HTML confidence: type: - string - 'null' enum: - Very High - High - Medium - Low - Unknown description: 'AI confidence in the answer. Present only on `bot_response` messages, and only when the model emitted a trailing confidence block. This field is now optional and nullable; it was previously always present and non-nullable. Treat a missing or `null` value as "no confidence reported" and guard before using it. Change effective in SDK v1.2.0 (v1.1.0 and earlier always populated it). ' citations: type: array description: Citations attached to this message. `citationData` is the populated citation document. items: type: object additionalProperties: false properties: citationId: type: string format: objectId citationData: $ref: '#/components/schemas/Citation' followUpQuestions: type: array items: $ref: '#/components/schemas/FollowUpQuestion' feedback: type: array items: $ref: '#/components/schemas/MessageFeedback' referenceData: type: array description: Reference IDs surfaced from tool responses, used for follow-up queries items: type: object additionalProperties: false properties: name: type: string description: Display name shown to the user. id: type: string description: Technical identifier (numeric ID, UUID, etc.). type: type: string description: Item type (e.g. `project`, `issue`, `file`, `notebook`, `page`). app: type: string description: 'Source application (e.g. `jira`, `confluence`, `sharepoint`, `slack`, `drive`, `gmail`). ' webUrl: type: string description: URL to open the item in a browser. metadata: type: object additionalProperties: type: string description: 'App-specific fields keyed by name (e.g. `key` for a Jira project, `siteId` for a SharePoint document). ' modelInfo: $ref: '#/components/schemas/ConversationModelInfo' appliedFilters: type: object additionalProperties: false properties: apps: type: array items: $ref: '#/components/schemas/AppliedFilterNode' kb: type: array items: $ref: '#/components/schemas/AppliedFilterNode' attachments: type: array description: 'Files uploaded for this message turn (see `POST /conversations/attachments/upload`). ' items: $ref: '#/components/schemas/ChatAttachmentRef' tools: type: array description: Tool call results invoked during this message turn. items: $ref: '#/components/schemas/MessageToolCall' reasoning: type: array description: Persisted chain-of-thought for this turn. items: $ref: '#/components/schemas/MessageReasoningTurn' parts: type: array description: Ordered agent-activity transcript for this turn. items: $ref: '#/components/schemas/MessagePart' metadata: type: object additionalProperties: false properties: processingTimeMs: type: number modelVersion: type: string aiTransactionId: type: string createdAt: type: string format: date-time updatedAt: type: string format: date-time modelInfo: $ref: '#/components/schemas/ConversationModelInfo' pagination: type: object additionalProperties: false description: 'Pagination over the conversation''s messages. Messages are paginated backwards (newest first), so `messageRange.start`/`messageRange.end` refer to 1-based positions within the full message list. ' properties: page: type: integer limit: type: integer totalCount: type: integer description: Total number of messages in the conversation totalPages: type: integer hasNextPage: type: boolean description: True if there are older messages available hasPrevPage: type: boolean description: True if there are newer messages available messageRange: type: object additionalProperties: false properties: start: type: integer end: type: integer access: type: object additionalProperties: false properties: isOwner: type: boolean accessLevel: type: string enum: - read - write sharedBy: $ref: '#/components/schemas/ConversationSharedBy' filters: type: object additionalProperties: false description: Summary of which filter/sort/pagination parameters were applied to this request, plus the catalog of options available on this endpoint. properties: applied: type: object additionalProperties: false properties: filters: type: array description: Names of the filters/parameters that were actually applied items: type: string values: type: object additionalProperties: true description: Map of applied filter name to the value that was applied available: type: object additionalProperties: false properties: shared: type: object additionalProperties: false properties: values: type: array items: type: string description: type: string current: type: - string - 'null' applied: type: boolean tags: type: object additionalProperties: false description: Advertised in the `available` catalog but not currently applied as a filter by the server. properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean minMessages: type: object additionalProperties: false description: Advertised in the `available` catalog but not currently applied as a filter by the server. properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean search: type: object additionalProperties: false properties: type: type: string description: type: string current: type: - string - 'null' applied: type: boolean pagination: type: object additionalProperties: false properties: page: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean limit: type: object additionalProperties: false properties: type: type: string current: type: integer min: type: integer max: type: integer default: type: integer description: type: string applied: type: boolean sorting: type: object additionalProperties: false description: Sort applied to the conversation list. Field set echoes back the original list-endpoint sort options even though this endpoint returns a single conversation. properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string applied: type: boolean sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string applied: type: boolean dateFilters: type: object additionalProperties: false properties: dateRange: type: object additionalProperties: false properties: type: type: string description: type: string format: type: string current: type: object additionalProperties: false properties: start: type: - string - 'null' end: type: - string - 'null' applied: type: boolean messageFilters: type: object additionalProperties: false properties: messageType: type: object additionalProperties: false properties: values: type: array items: type: string description: type: string current: type: - string - 'null' applied: type: boolean sortingMessages: type: object additionalProperties: false description: Sort applied to messages within the conversation (separate from the conversation-list `sorting` block). properties: sortBy: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string sortOrder: type: object additionalProperties: false properties: values: type: array items: type: string default: type: string description: type: string current: type: string meta: type: object additionalProperties: false properties: requestId: type: string timestamp: type: string format: date-time duration: type: integer description: Server processing time in milliseconds conversationId: type: string format: objectId messageCount: type: integer description: Total number of messages in the conversation '401': description: Unauthorized '403': description: Forbidden - No access to this conversation '404': description: Conversation not found delete: tags: - Conversations summary: Delete conversation description: 'Delete a conversation by its ID. **Overview:** Performs a soft delete by setting `isDeleted: true`. The conversation is removed from listings but preserved in the database. All citations referenced by messages in the conversation are also soft-deleted. **Permissions:** The conversation initiator can always delete. Users the conversation has been shared with may delete it only when their `sharedWith.accessLevel` is `write`.' operationId: deleteConversationById x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId responses: '200': description: Conversation deleted successfully content: application/json: schema: type: object additionalProperties: false properties: id: type: string format: objectId description: Identifier of the conversation that was deleted status: type: string enum: - deleted description: Outcome of the operation deletedAt: type: string format: date-time description: Timestamp when the conversation was marked deleted deletedBy: type: string format: objectId description: Identifier of the user who performed the delete citationsDeleted: type: integer description: Number of citations soft-deleted alongside the conversation meta: type: object additionalProperties: false properties: requestId: type: string description: Server-assigned identifier for the request timestamp: type: string format: date-time description: Server time the response was produced duration: type: integer description: Server processing time in milliseconds '400': description: Invalid `conversationId` path parameter '401': description: Unauthorized '403': description: Forbidden - token is missing the `conversation:write` scope '404': description: Conversation not found, already deleted, or caller has no delete access '500': description: Internal server error while deleting the conversation servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/messages: post: tags: - Conversations summary: Add message (non-streaming) description: 'Ask a follow-up in an existing assistant conversation and wait for the complete answer. The JSON counterpart of `POST /conversations/{conversationId}/messages/stream`. Earlier turns are sent to the model as history; project context comes from the conversation, never from the request. **How a turn runs** 1. The user''s message is saved (in its own short transaction on a replica set). 2. The AI backend runs the same agent-loop pipeline as the `/stream` route and returns only its final result. No transaction is held during this call, and the call is never retried. 3. The answer, citations and status are saved exactly as the streaming route saves them, and the updated conversation is returned. Every failure after step 1 is persisted: the conversation ends with status `Failed`, a `failReason`, and an `error` message, and the response carries `X-Conversation-Id` so the caller can fetch it. A 4xx from the AI backend (for example no model configured) keeps its status and user-facing message; other failures return 500 with a generic message. The response arrives only when the whole answer is ready, which can take minutes for agent runs. Allow a generous client and proxy timeout, or use the `/stream` variant for interactive clients.' operationId: addMessage x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:chat parameters: - name: conversationId in: path required: true schema: type: string format: objectId requestBody: required: true description: The follow-up question, with optional scope and model overrides. content: application/json: schema: $ref: '#/components/schemas/AddMessageRequest' responses: '200': description: The conversation with the new question and answer. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/AddMessageResponse' '400': description: 'Invalid request — `query` is missing or empty, contains markup or printf-style format specifiers, or another field fails validation. ' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized — valid bearer token required. '403': description: Forbidden — the token lacks the `conversation:chat` OAuth scope. '404': description: 'Conversation not found — it does not exist, belongs to another user, is of the other type (assistant vs agent), or, for agent routes, belongs to a different agent. ' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '413': description: The request is larger than the selected model accepts. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '422': description: The model provider's content filter blocked the request. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '424': description: 'No usable LLM — none is configured for the organization, or the selected one could not start. The message says what to fix. ' headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '429': description: The model provider is rate limiting or out of quota. headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' '500': description: 'The answer failed (AI service unreachable, timed out, returned no answer, or could not be saved). The conversation is kept with status `Failed` and an `error` message. ' headers: X-Conversation-Id: $ref: '#/components/headers/X-Conversation-Id' content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/messages/stream: post: tags: - Conversations summary: Add message to a conversation with streaming response description: 'Add a follow-up message to an existing conversation and stream the assistant''s response over Server-Sent Events. Functionally equivalent to `POST /conversations/{conversationId}/messages` but the response is delivered as an SSE stream so clients can render the answer incrementally. AG-UI is the sole wire protocol. The vocabulary is described by `ConversationMessageStreamSSEEvent`; it is the same event set as `/conversations/stream`, while the terminal result reflects an existing conversation.' operationId: addMessageStream x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:chat parameters: - name: conversationId in: path required: true description: 'Identifier of the conversation to append the message to. The conversation must belong to the caller and must not be deleted. ' schema: type: string format: objectId requestBody: required: true description: Request payload content: application/json: schema: $ref: '#/components/schemas/ConversationMessageStreamRequest' responses: '200': description: 'SSE stream established. The body is a sequence of `text/event-stream` frames using the event vocabulary described on the schema below. ' content: text/event-stream: schema: $ref: '#/components/schemas/ConversationMessageStreamSSEEvent' '400': description: 'Invalid request — `query` is missing or empty, or another field fails validation (for example a malformed `currentTime`). ' '401': description: Unauthorized — valid bearer token required. '403': description: 'Forbidden — the caller''s token does not include the `conversation:chat` OAuth scope. ' '404': description: 'The conversation does not exist, is deleted, or does not belong to the caller. ' '500': description: 'Internal error before the SSE stream is established (for example, the user message could not be persisted to the conversation). Once the stream is open, terminal failures are surfaced as a `RUN_ERROR` SSE event instead of an HTTP status change. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/share: post: tags: - Conversations summary: Share conversation with users description: 'Share a conversation with other users in your organization. **Overview:** Allows the conversation owner to grant access to other users. Shared users can view the conversation and optionally add messages. **Access Levels:** - `read` - Can view conversation and messages (default) - `write` - Can view and add new messages **Permissions:** Only the conversation initiator (owner) can share. Users must belong to the same organization.' operationId: shareConversation security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true description: Request payload content: application/json: schema: $ref: '#/components/schemas/ShareRequest' responses: '200': description: Conversation shared successfully content: application/json: schema: type: object additionalProperties: false required: - id - isShared - sharedWith - meta properties: id: type: string format: objectId description: Conversation identifier isShared: type: boolean description: Always `true` after a successful share sharedWith: type: array description: Full list of users the conversation is now shared with, including pre-existing entries. items: type: object additionalProperties: false required: - userId - accessLevel - _id properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write _id: type: string format: objectId description: Subdocument identifier auto-assigned by MongoDB. meta: type: object additionalProperties: false required: - requestId - timestamp - duration properties: requestId: type: string description: 'Server-side request identifier. Read from the `X-Request-ID` header when supplied, otherwise auto-generated, so this field is always present. ' timestamp: type: string format: date-time duration: type: integer description: Server-side processing time in milliseconds. '400': description: Invalid request - userIds array required '401': description: Unauthorized '403': description: Forbidden - Only owner can share '404': description: Conversation or users not found servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/title: patch: tags: - Conversations summary: Update conversation title description: 'Update the title of a conversation. **Overview:** Conversation titles are auto-generated from the first query by default. Use this endpoint to set a custom, more descriptive title. **Title limits:** - Minimum: 1 character - Maximum: 200 characters **Permissions:** The conversation must exist, belong to the calling user''s organization, be owned by the caller (matched on `userId`), and not be soft-deleted.' operationId: updateConversationTitle x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true description: Request payload content: application/json: schema: type: object additionalProperties: false required: - title properties: title: type: string minLength: 1 maxLength: 200 description: New conversation title example: Q4 Sales Analysis Discussion responses: '200': description: Title updated successfully content: application/json: schema: type: object additionalProperties: false required: - conversation - meta properties: conversation: type: object additionalProperties: false description: 'The conversation document after the title update, as stored in the `chatSessions` collection. Carries no `messages`: they live in `chatSessionMessages` (see `chat.session.schema.ts`) and this route neither reads nor joins them. Fetch the conversation by id to get its messages. ' required: - _id - userId - orgId - initiator - isShared - isDeleted - isArchived - sharedWith - conversationErrors - lastActivityAt - createdAt - updatedAt - __v properties: _id: type: string format: objectId description: Unique conversation identifier userId: type: string format: objectId description: ID of the user who owns this conversation orgId: type: string format: objectId description: Organization this conversation belongs to title: type: string description: 'Conversation title. Present and equal to the value submitted in the request body after a successful update. ' initiator: type: string format: objectId description: User who started the conversation status: type: string enum: - None - Inprogress - Complete - Failed - Stopped description: 'Current status of the conversation: - `None` — no activity yet - `Inprogress` — AI is processing - `Complete` — response ready - `Failed` — error occurred - `Stopped` — cancelled, or the client disconnected mid-answer ' failReason: type: string description: 'Error description, populated only when `status` is `Failed`. ' modelInfo: $ref: '#/components/schemas/ConversationModelInfo' isShared: type: boolean default: false description: Whether this conversation is shared with others shareLink: type: string description: Shareable link if the conversation is shared sharedWith: type: array description: Users this conversation is shared with items: type: object additionalProperties: false required: - userId - accessLevel properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write default: read isArchived: type: boolean default: false description: Whether this conversation is archived archivedBy: type: - string - 'null' format: objectId description: 'User ID of the last user who archived this row, or `null` after unarchive cleared the archive state. Absent on rows that have never been archived. ' isDeleted: type: boolean default: false description: Whether this conversation has been soft-deleted. deletedBy: type: string format: objectId description: User who soft-deleted this conversation. conversationErrors: type: array description: 'Errors recorded against this conversation (e.g. failed message generations). ' items: type: object additionalProperties: false required: - _id - message - timestamp properties: _id: type: string format: objectId description: Sub-document identifier auto-assigned by MongoDB. message: type: string errorType: type: string timestamp: type: string format: date-time description: 'Time the error was recorded. Server-defaulted to `Date.now` when the entry is pushed, so always present. ' messageId: type: string format: objectId stack: type: string metadata: type: object additionalProperties: true description: 'Free-form metadata attached to this error entry (Map of Mixed in the schema). ' metadata: type: object additionalProperties: true description: Free-form metadata attached to the conversation. lastActivityAt: type: integer format: int64 description: 'Unix timestamp of the last activity, stored as epoch milliseconds (server-side default `Date.now`). ' createdAt: type: string format: date-time updatedAt: type: string format: date-time __v: type: integer description: Mongoose document version key. meta: type: object additionalProperties: false required: - requestId - timestamp - duration properties: requestId: type: string description: 'Server-side request identifier. Read from the `X-Request-ID` header when supplied, otherwise auto-generated, so this field is always present. ' timestamp: type: string format: date-time duration: type: integer description: Server-side processing time in milliseconds. '400': description: 'Invalid request. Possible causes: - `title` missing, empty, or longer than 200 characters. - `conversationId` path parameter is not a valid ObjectId. ' '401': description: Unauthorized '403': description: Forbidden - token is missing the `conversation:write` scope '404': description: Conversation not found, soft-deleted, or not owned by the caller. '500': description: Persistence layer failed to update the conversation document. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/archive: patch: tags: - Conversations summary: Archive conversation description: 'Archive a conversation to hide it from the main list. **Overview:** Archived conversations are preserved but hidden from the default conversation list. Use archiving to clean up your workspace without permanently deleting conversations. **Access:** The caller must be the conversation''s initiator, or be listed in `sharedWith` with `accessLevel: write`. Already-archived conversations return `400`. **Retrieval:** View archived conversations using `GET /conversations/show/archives`. Restore one with `PATCH /conversations/{conversationId}/unarchive`.' operationId: archiveConversation x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Conversation identifier schema: type: string format: objectId responses: '200': description: Conversation archived successfully content: application/json: schema: type: object additionalProperties: false properties: id: type: string format: objectId description: Conversation identifier status: type: string enum: - archived description: New archive status of the conversation archivedBy: type: string format: objectId description: User who archived the conversation archivedAt: type: string format: date-time description: Timestamp when the conversation was archived meta: type: object additionalProperties: false properties: requestId: type: string description: Request correlation identifier timestamp: type: string format: date-time description: Response generation timestamp duration: type: integer description: Server processing time in milliseconds '400': description: Conversation is already archived '401': description: Unauthorized '404': description: Conversation not found or caller lacks archive permission servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/unarchive: patch: tags: - Conversations summary: Unarchive conversation description: 'Restore an archived conversation. - Path params: `conversationId` - Query params: none - Body: none' operationId: unarchiveConversation x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Conversation identifier schema: type: string format: objectId responses: '200': description: Conversation unarchived successfully content: application/json: schema: type: object additionalProperties: false properties: id: type: string format: objectId description: Conversation identifier status: type: string enum: - unarchived description: New archive status of the conversation unarchivedBy: type: string format: objectId description: User who unarchived the conversation unarchivedAt: type: string format: date-time description: Timestamp when the conversation was unarchived meta: type: object additionalProperties: false properties: requestId: type: string description: Request correlation identifier timestamp: type: string format: date-time description: Response generation timestamp duration: type: integer description: Server processing time in milliseconds '400': description: Conversation is not currently archived '401': description: Unauthorized '403': description: Forbidden - token is missing the `conversation:write` scope '404': description: Conversation not found or caller lacks unarchive permission '500': description: Persistence layer failed to update the conversation document. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/message/{messageId}/regenerate: post: tags: - Conversations summary: Regenerate AI response description: 'Regenerate the AI response for a specific message and stream the new answer over Server-Sent Events. **Overview:** If you''re not satisfied with an AI response, use this endpoint to generate a new answer. The original user query is re-processed and a new bot response replaces the previous one in place. **Constraints:** - Only the *last* message of the conversation can be regenerated. - The target message must be of type `bot_response`. **Use Cases:** - Response was incomplete or unclear - Want to try a different AI model - New documents have been indexed since original response **Model Override:** Specify `modelKey` to use a different model for regeneration. **Streaming:** The response is delivered as an AG-UI `text/event-stream` stream. Routing still depends on `chatMode`: `internal_search` and `web_search` use the assistant backend, while `agent` uses the universal agent loop. See `SSEEvent` for the event vocabulary.' operationId: regenerateAnswer x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:chat parameters: - name: conversationId in: path required: true schema: type: string format: objectId - name: messageId in: path required: true description: ID of the message to regenerate response for schema: type: string format: objectId requestBody: description: Request payload content: application/json: schema: $ref: '#/components/schemas/RegenerateRequest' responses: '200': description: 'SSE stream established. The body is a sequence of `text/event-stream` frames using the event vocabulary described on `SSEEvent`. The exact subset of events emitted depends on `chatMode` (see the route description for routing rules). The gateway emits a root `RUN_FINISHED` as `{ type, result }` after persistence and a root `RUN_ERROR` as `{ type, message, code? }` on failure. Forwarded lifecycle and child-run events may contain `runId`, `threadId`, and `parentRunId`. Clients should ignore unknown event names. ' content: text/event-stream: schema: $ref: '#/components/schemas/SSEEvent' '400': description: 'Cannot regenerate. Common causes: target message is not the last message in the conversation, target message is not of type `bot_response`, or no preceding `user_query` exists. ' '401': description: Unauthorized '404': description: Conversation or message not found servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/cancel: post: tags: - Conversations summary: Cancel an in-flight chat stream description: 'Cooperatively stop a `POST /conversations/stream` or `POST /conversations/{conversationId}/messages/stream` run that is still generating, using the `runId` sent when that stream started. This is a synchronous JSON ack, not another SSE stream. The cancelled run''s own stream (if still connected) receives a terminal frame with a `stopped` status and whatever partial answer had already generated; nothing further is delivered here. `{ cancelled: false }` — not an error — covers a `runId` that already finished or was never registered; the caller only needs to know the stream is not running anymore, not why. `runId` must belong to a run started on THIS `conversationId` — a `runId` that exists but was registered under a different conversation (even one owned by the same caller) is rejected with `403`, same as a `runId` owned by a different user/org.' operationId: cancelConversationStream x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:chat parameters: - name: conversationId in: path required: true schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object required: - runId properties: runId: type: string format: uuid description: The `runId` sent when the stream was started. responses: '200': description: Cancellation requested, or the run had already finished. content: application/json: schema: type: object properties: cancelled: type: boolean '400': description: Missing or malformed `runId`. '401': description: Unauthorized '403': description: '`runId` exists but was registered under a different user, org, or conversation than this request.' '404': description: Conversation not found or unauthorized servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/message/{messageId}/feedback: post: tags: - Conversations summary: Submit feedback on AI response description: 'Append a feedback entry to a bot-response message. **Overview** Feedback helps improve AI response quality over time. You can record an overall helpfulness signal, issue categories, and free-text comments. Each call appends a new entry to the message; previous entries are preserved. **Feedback options** - `isHelpful` — overall thumbs up/down. - `categories` — issue or positive categories from a fixed list. - `comments` — free-text `positive` and `negative`. **Restrictions** Feedback can only be submitted on `bot_response` messages — user queries and system messages are rejected with `400`.' operationId: updateMessageFeedback x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier. schema: type: string format: objectId - name: messageId in: path required: true description: Identifier of the bot-response message being rated. schema: type: string format: objectId requestBody: required: true description: Request payload content: application/json: schema: $ref: '#/components/schemas/MessageFeedbackSubmitRequest' responses: '200': description: Feedback submitted successfully. content: application/json: schema: $ref: '#/components/schemas/MessageFeedbackUpdateResponse' '400': description: 'Invalid request. Possible causes: - Feedback target is not a `bot_response` message. - A `categories` value is not in the allowed list. - `conversationId` or `messageId` is not a valid ObjectId. ' '401': description: Unauthorized. '404': description: 'Conversation or message not found, or the caller does not have access to this conversation. ' '500': description: Persistence layer failed to append the feedback entry. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/unshare: post: tags: - Conversations summary: Unshare a conversation description: Revoke sharing for a conversation, making it private again. operationId: unshareConversationById security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true description: Request payload content: application/json: schema: type: object additionalProperties: false required: - userIds properties: userIds: type: array items: type: string format: objectId minItems: 1 description: IDs of users to remove from the conversation's share list. example: - 507f1f77bcf86cd799439011 responses: '200': description: Conversation unshared successfully content: application/json: schema: type: object additionalProperties: false required: - id - isShared - sharedWith - unsharedUsers - meta properties: id: type: string format: objectId description: Conversation identifier isShared: type: boolean description: 'Reset to `false` when the last user is removed; otherwise remains `true`. ' sharedWith: type: array description: 'Remaining users with access after the requested userIds were removed. Empty array when no one is left. ' items: type: object additionalProperties: false required: - userId - accessLevel - _id properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write _id: type: string format: objectId description: Subdocument identifier auto-assigned by MongoDB. unsharedUsers: type: array description: Echo of the `userIds` from the request body. items: type: string format: objectId meta: type: object additionalProperties: false required: - requestId - timestamp - duration properties: requestId: type: string description: 'Server-side request identifier. Read from the `X-Request-ID` header when supplied, otherwise auto-generated, so this field is always present. ' timestamp: type: string format: date-time duration: type: integer description: Server-side processing time in milliseconds. '400': description: 'Invalid request. Possible causes: - `userIds` empty, missing, or not an array. - One or more `userIds` is not a valid ObjectId. ' '401': description: Unauthorized '404': description: Conversation not found, or caller is not the initiator. '500': description: Persistence layer failed to update the conversation document. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/project: put: tags: - Conversations summary: Link or unlink a conversation to a project description: 'Set (`projectId: `) or clear (`projectId: null`) the project this conversation belongs to. Initiator-only. **Access:** The caller must be the conversation''s initiator. Linking to a non-null `projectId` also requires at least viewer access to that project (`404` if not visible to the caller — never `403`, to avoid leaking project existence across an org boundary). **Visibility on link:** When linking, `projectVisibility` defaults from the project''s `chatSharing` setting (`members` → `project`, otherwise `private`) unless the conversation was already `project`-visible, in which case that is preserved. Use `PATCH /conversations/{conversationId}/project-visibility` to override it explicitly. Unlinking (`projectId: null`) always clears both `projectId` and `projectVisibility`.' operationId: setConversationProject x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - projectId properties: projectId: type: - string - 'null' format: objectId description: Target project id, or `null` to unlink. responses: '200': description: Conversation's project link updated content: application/json: schema: type: object additionalProperties: false required: - conversationId properties: conversationId: type: string format: objectId projectId: type: - string - 'null' format: objectId projectVisibility: type: - string - 'null' enum: - private - project '400': description: '`projectId` missing or not a valid ObjectId/`null`.' '401': description: Unauthorized '404': description: 'Conversation not found or caller is not the initiator, or the target project does not exist or is not visible to the caller. ' servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /conversations/{conversationId}/project-visibility: patch: tags: - Conversations summary: Override a conversation's project visibility description: 'Explicitly set whether a project-linked conversation is visible to other members of that project (`project`) or only to its owner (`private`). Initiator-only. Requires the conversation to already be linked to a project via `PUT /conversations/{conversationId}/project`.' operationId: setConversationProjectVisibility x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - conversation:write parameters: - name: conversationId in: path required: true description: Unique conversation identifier schema: type: string format: objectId requestBody: required: true content: application/json: schema: type: object additionalProperties: false required: - visibility properties: visibility: type: string enum: - private - project responses: '200': description: Conversation's project visibility updated content: application/json: schema: type: object additionalProperties: false required: - conversationId - projectVisibility properties: conversationId: type: string format: objectId projectVisibility: type: string enum: - private - project '400': description: '`visibility` missing/invalid, or the conversation is not linked to a project. ' '401': description: Unauthorized '404': description: Conversation not found or caller is not the initiator. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL /projects/{projectId}/conversations: get: tags: - Conversations summary: List a project's conversations description: 'Requires viewer access to the project. Returns both chat and agent sessions (`chatSessions`, discriminated by `sessionType`/`agentKey`) that the caller may see: rows they own, plus rows with `projectVisibility: project`. Access to the project is asserted first, so a private conversation belonging to a *different* project member never leaks through this endpoint.' operationId: getProjectConversations x-pipeshub-sdk: true security: - bearerAuth: [] - oauth2: - project:read parameters: - name: projectId in: path required: true schema: type: string format: objectId - name: page in: query schema: type: integer minimum: 1 default: 1 - name: limit in: query schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Paginated conversations linked to the project content: application/json: schema: type: object additionalProperties: false required: - conversations - pagination properties: conversations: type: array items: $ref: '#/components/schemas/ConversationListItem' pagination: type: object additionalProperties: false properties: page: type: integer limit: type: integer totalCount: type: integer totalPages: type: integer '401': description: Unauthorized '404': description: Project not found or not visible to the caller. servers: - url: '{instance_url}/api/v1' description: Base API URL variables: instance_url: default: https://app.pipeshub.com description: Base server URL (without /api/v1) - url: '{instance_url}' description: Root URL (used for MCP endpoints mounted at /mcp) variables: instance_url: default: https://app.pipeshub.com description: Base server URL components: schemas: AddMessageResponse: type: object additionalProperties: false description: 'Envelope returned by `POST /conversations/{conversationId}/messages`. Contains the updated conversation, the number of citation records used to ground the AI response for this turn, and request metadata. ' required: - conversation - recordsUsed - meta properties: conversation: $ref: '#/components/schemas/Conversation' recordsUsed: type: integer minimum: 0 description: 'Number of citation records used to ground the AI response generated for this turn. ' meta: type: object additionalProperties: false required: - timestamp - duration properties: requestId: type: string description: 'Request correlation id. Omitted when upstream middleware did not set `req.context.requestId`. ' timestamp: type: string format: date-time description: Server timestamp when the response was sent. duration: type: integer minimum: 0 description: Total handler duration in milliseconds. recordsUsed: type: integer minimum: 0 description: 'Same value as the top-level `recordsUsed`. Duplicated inside `meta` for client convenience. ' MessageReasoningTurn: type: object additionalProperties: false description: 'One model turn''s chain-of-thought. Persisted only when reasoning persistence is enabled; the array is empty otherwise. ' required: - content properties: messageId: type: string turnIndex: type: number content: type: string AppliedFilterNode: type: object additionalProperties: false description: A single filter node selected by the user (used for display/persistence of active filters) properties: id: type: string description: Unique identifier of the filter node name: type: string description: Display name of the filter node nodeType: type: string description: Type of the node (e.g. app, recordGroup, folder, record) connector: type: string description: Connector identifier associated with this node Message: type: object additionalProperties: false description: 'A single message within a conversation. Messages can be user queries, AI responses, system messages, or error notifications. ' properties: _id: type: string format: objectId description: Unique message identifier messageType: type: string enum: - user_query - bot_response - error - feedback - system - tool_call description: 'Type of message: - `user_query` - User''s question or input - `bot_response` - AI-generated response - `error` - Error message from the system - `feedback` - User feedback on a response - `system` - System notification or status - `tool_call` - Tool invocation turn; details are on `tools` ' content: type: string description: The message text content contentFormat: type: string enum: - MARKDOWN - JSON - HTML description: Format of the content for rendering default: MARKDOWN citations: type: array items: anyOf: - $ref: '#/components/schemas/CitationReference' - $ref: '#/components/schemas/PopulatedCitationReference' description: 'References to source documents used in the response. Routes that return the saved conversation after a turn (create, add message) populate each item to `{ citationId, citationData }`. ' confidence: type: - string - 'null' description: 'AI confidence in the answer. Present only on `bot_response` messages, and only when the model emitted a trailing confidence block. This field is now optional and nullable; it was previously always present and non-nullable. Treat a missing or `null` value as "no confidence reported" and guard before using it. Change effective in SDK v1.3.0 (v1.2.0 and earlier always populated it). ' followUpQuestions: type: array items: $ref: '#/components/schemas/FollowUpQuestion' description: Suggested follow-up questions feedback: type: array items: $ref: '#/components/schemas/MessageFeedback' description: User feedback on this message metadata: type: object additionalProperties: false properties: processingTimeMs: type: number description: Time taken to generate response in milliseconds modelVersion: type: string description: Version of the AI model used aiTransactionId: type: string description: Transaction ID for tracking in AI backend reason: type: string description: Additional context or reasoning modelInfo: $ref: '#/components/schemas/ConversationModelInfo' appliedFilters: $ref: '#/components/schemas/AppliedFilters' referenceData: type: array description: 'Reference identifiers extracted from tool responses, used to scope follow-up queries (for example Jira project keys or record IDs). ' items: type: object additionalProperties: false properties: name: type: string description: Display name shown to the user. id: type: string description: Technical identifier (numeric ID, UUID, etc.). type: type: string description: Item type (e.g. `project`, `issue`, `file`, `notebook`, `page`). app: type: string description: 'Source application (e.g. `jira`, `confluence`, `sharepoint`, `slack`, `drive`, `gmail`). ' webUrl: type: string description: URL to open the item in a browser. metadata: type: object additionalProperties: type: string description: 'App-specific fields keyed by name (e.g. `key` for a Jira project, `siteId` for a SharePoint document). ' attachments: type: array description: 'Files uploaded for this message turn (see `POST /conversations/attachments/upload`). ' items: $ref: '#/components/schemas/ChatAttachmentRef' tools: type: array description: Tool call results invoked during this message turn. items: $ref: '#/components/schemas/MessageToolCall' reasoning: type: array description: Persisted chain-of-thought for this turn. items: $ref: '#/components/schemas/MessageReasoningTurn' parts: type: array description: Ordered agent-activity transcript for this turn. items: $ref: '#/components/schemas/MessagePart' createdAt: type: string format: date-time updatedAt: type: string format: date-time ShareRequest: type: object description: Request to share a conversation or search with other users required: - userIds properties: userIds: type: array items: type: string format: objectId minItems: 1 description: IDs of users to share with example: - 507f1f77bcf86cd799439011 accessLevel: type: string enum: - read - write default: read description: 'Permission level for shared users: - `read` — Can view only - `write` — Can add messages ' Filters: type: object additionalProperties: false description: 'App connector instance ids and knowledge-base / record-group ids that narrow retrieval for a turn. For **org assistant** chat streams, send explicit `apps` / `kb` lists. For **agent** chat streams, send explicit id lists, or **omit** `filters` (and `tools`) to let the service use the agent’s stored knowledge and tool configuration. Sending `{ "apps": [], "kb": [] }` on an agent stream means **no** knowledge sources for that turn (it is not “full org default”). ' properties: apps: type: array items: type: string description: 'Connector instance ids to scope retrieval for this turn. Each element must be a valid UUID (connector app id, KB app id, record-group id, etc.). Gateway validation matches Zod `appOrKbIdSchema`. ' kb: type: array items: type: string description: 'Knowledge-base app ids to scope retrieval for this turn. Each element must be a valid UUID. ' ChatAttachmentRef: type: object additionalProperties: false description: 'Reference to an attachment produced by `POST /conversations/attachments/upload` (or the equivalent agent route). Include in create/stream/message bodies so the turn is sent with uploaded files. ' required: - recordId properties: recordId: type: string minLength: 1 description: Attachment record id returned from the upload endpoint. recordName: type: string minLength: 1 description: Original display name of the file when known. mimeType: type: string minLength: 1 description: MIME type of the uploaded file. extension: type: string minLength: 1 description: File extension (e.g. `pdf`). virtualRecordId: type: string minLength: 1 description: Optional synthetic record id used by the graph layer. CitationReference: type: object additionalProperties: false description: Reference to a source document cited in a response properties: citationId: type: string format: objectId description: ID of the citation record relevanceScore: type: number minimum: 0 maximum: 1 description: How relevant this citation is to the query (0-1) excerpt: type: string description: Relevant excerpt from the source document context: type: string description: Additional context around the citation ErrorResponse: type: object additionalProperties: false description: 'Standard error envelope returned by all errors routed through `ErrorMiddleware`. Applies to all `BaseError` subclasses including `HttpError`, `ValidationError`, and others. The `code` field is a machine-readable string identifying the error type (e.g. `HTTP_UNAUTHORIZED`, `HTTP_NOT_FOUND`, `VALIDATION_ERROR`, `INTERNAL_ERROR`). ' properties: error: type: object additionalProperties: false required: - code - message properties: requestId: type: string description: 'Identifier for this request, echoed so a bug report can quote it. Absent when the request never reached the middleware that assigns one. ' code: type: string description: 'Machine-readable error code. For application errors it takes the form `HTTP_` For unhandled runtime errors (e.g. database unavailable) it is `INTERNAL_ERROR`. ' example: HTTP_BAD_REQUEST message: type: string description: Human-readable description of the error example: Admin access required metadata: type: object description: Additional context (only present in development environments) additionalProperties: true required: - error FollowUpQuestion: type: object additionalProperties: false description: AI-suggested follow-up question properties: question: type: string description: The suggested question text confidence: type: string description: Confidence level for this suggestion reasoning: type: string description: Why this question might be relevant CreateConversationRequest: type: object description: 'Request body for creating a new AI conversation. **Query Processing:** The query is processed through PipesHub''s AI pipeline which: - Performs semantic search across indexed knowledge bases - Retrieves relevant context from matching documents - Generates a response with citations to source materials - Suggests follow-up questions based on the conversation ' required: - query properties: query: type: string minLength: 1 maxLength: 100000 description: 'The user''s question or prompt to start the conversation. Supports natural language queries of any complexity. ' example: What are the key findings from our Q4 financial report? recordIds: type: array items: type: string format: objectId description: 'Limit the AI''s knowledge scope to specific records/documents. When provided, only these records will be searched for context. ' example: - 507f1f77bcf86cd799439011 - 507f1f77bcf86cd799439012 filters: $ref: '#/components/schemas/Filters' appliedFilters: $ref: '#/components/schemas/AppliedFilters' attachments: type: array items: $ref: '#/components/schemas/ChatAttachmentRef' description: 'Uploaded chat attachments to associate with this conversation turn (see `POST /conversations/attachments/upload`). ' projectId: type: string format: objectId description: 'Link the new conversation to a project the caller has at least viewer access to. When the project''s instructions, knowledge scope, or files are set and this request didn''t supply its own `filters`/`attachments`, they are merged in as a fallback (the request always wins). Ignored on follow-up turns — only meaningful when creating a conversation. ' projectVisibility: type: string enum: - private - project description: 'Only meaningful together with `projectId`. Overrides the project''s default sharing behavior for this one conversation: `private` keeps it visible to the owner only; `project` exposes it to every project member. Defaults from the project''s `chatSharing` setting when omitted. ' modelKey: type: string description: 'Identifier for the AI model configuration to use. Available models depend on organization settings. ' example: gpt-5.6-luna modelName: type: string description: Display name of the AI model example: gpt-5.6-luna modelFriendlyName: type: string description: Friendly display name of the selected model example: gpt-5.6-Luna chatMode: type: string enum: - agent - internal_search - web_search description: 'Optional execution mode for non-stream consumers of this shared request schema. `agent` uses the universal agent loop, while `internal_search` and `web_search` use their corresponding assistant search paths. ' example: internal_search timezone: type: string minLength: 1 description: 'IANA timezone identifier from the client (top-level field). Used to provide time-aware context to the AI. ' example: America/New_York currentTime: type: string format: date-time description: 'ISO 8601 / RFC 3339 datetime from the client (top-level field; UTC `Z` or numeric offset). ' example: '2026-04-12T16:00:00+05:30' tools: type: array items: type: string minLength: 1 description: 'Optional list of tool identifiers (fully-qualified action names such as "jira.create_issue") that the AI agent is permitted to invoke for this request. When omitted the agent may use any configured tool. Applicable only when `chatMode` is `agent`. ' example: - jira.create_issue - confluence.search_content protocol: type: string enum: - agui description: 'AG-UI is the only supported wire protocol. When present must be `"agui"`. Omitting the field is equivalent — the server always uses the AG-UI vocabulary (`RUN_STARTED`, `TEXT_MESSAGE_CONTENT`, etc.). Kept in the schema for backward compatibility with callers that already send it. ' agentCapabilities: $ref: '#/components/schemas/AgentCapabilities' runId: type: string format: uuid description: 'Client-generated identifier for this run. Send it here to enable `POST /conversations/{conversationId}/cancel {runId}` while the stream is still generating. Optional — a caller that never sends one just can''t cooperatively cancel the run. ' AgentCapabilities: type: object additionalProperties: false description: 'Per-request agent capability toggles. Only meaningful when `chatMode` selects an agent mode; ignored otherwise. Each field falls back to its own `default` below when omitted — a missing flag is not uniformly `true`. Omitting the whole object applies every default. ' properties: internalSearch: type: boolean default: true description: Whether the agent may search internal knowledge bases for this turn. webSearch: type: boolean default: true description: Whether the agent may perform web search for this turn. deepSearch: type: boolean default: false description: Whether the agent may use deeper, higher-latency retrieval for this turn. ConversationStreamSSEEvent: type: object description: "Server-Sent Event envelope for public conversation streams using\n`agent`, `internal_search`, or `web_search`. AG-UI is the sole wire\nprotocol.\n\n`event` carries the AG-UI type name and `data` is a JSON-encoded\nobject that includes a `\"type\"` field matching `event`, plus\ntype-specific fields. Universal `agent` mode may emit `STEP_STARTED`,\n`STEP_FINISHED`, and nested child-run events carrying `parentRunId`.\nStable gateway-generated top-level outcomes:\n\n- `CUSTOM` (`name: \"conversation_created\"`) — fired once on\n connection. Carries the newly created `conversationId` and\n `title` so the client can link the stream to the new row before\n any tokens arrive.\n- `RUN_FINISHED` — fired once after the AI backend finishes.\n The gateway emits `{ type, result }`; `result` carries the full\n persisted `conversation` and a `meta` block.\n- `RUN_ERROR` — fired when the stream fails. Carries a `message`\n and optional `code`; the conversation row is marked FAILED\n before close.\n\nForwarded upstream lifecycle or child-run events may contain `runId`,\n`threadId`, and `parentRunId`. Gateway-generated root terminal events\ndo not.\nClients should ignore unknown event names rather than treating them\nas errors.\n" properties: event: type: string enum: - RUN_STARTED - RUN_FINISHED - RUN_ERROR - STEP_STARTED - STEP_FINISHED - TEXT_MESSAGE_START - TEXT_MESSAGE_CONTENT - TEXT_MESSAGE_END - REASONING_START - REASONING_MESSAGE_START - REASONING_MESSAGE_CONTENT - REASONING_MESSAGE_END - REASONING_END - TOOL_CALL_START - TOOL_CALL_ARGS - TOOL_CALL_END - TOOL_CALL_RESULT - STATE_DELTA - STATE_SNAPSHOT - CUSTOM - HEARTBEAT data: type: string description: 'JSON-encoded event payload. The decoded JSON includes a `"type"` field matching `event`, plus type-specific fields. Shape depends on `event`. Forwarded lifecycle events may carry `runId`, `threadId`, and `parentRunId`. ' Conversation: type: object description: 'A conversation represents a chat session between a user and the AI. Conversations maintain context across multiple messages and can be shared, archived, and organized. ' properties: _id: type: string format: objectId description: Unique conversation identifier userId: type: string format: objectId description: ID of the user who owns this conversation orgId: type: string format: objectId description: Organization this conversation belongs to title: type: string description: 'Conversation title, auto-generated from first query or manually updated ' example: Q4 Financial Report Discussion initiator: type: string format: objectId description: User who started the conversation messages: type: array items: $ref: '#/components/schemas/Message' description: All messages in this conversation status: type: string enum: - None - Inprogress - Complete - Failed - Stopped description: "Current status of the conversation:\n- `None` — no activity yet\n- `Inprogress` — AI is processing\n- `Complete` — response ready\n- `Failed` — error occurred\n- `Stopped` — cancelled, or the client disconnected mid-answer;\n the last message keeps the partial answer\n" failReason: type: string description: Error description, populated only when `status` is `Failed`. modelInfo: type: object properties: modelKey: type: string modelName: type: string modelFriendlyName: type: string description: Friendly display name of the selected model modelProvider: type: string chatMode: type: string description: AI model configuration used isShared: type: boolean default: false description: Whether this conversation is shared with others shareLink: type: string description: Shareable link if conversation is shared sharedWith: type: array items: type: object properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write description: Users this conversation is shared with isArchived: type: boolean default: false description: Whether this conversation is archived archivedBy: type: - string - 'null' format: objectId description: 'User ID of the last user who archived this row, or `null` after unarchive cleared the archive state. Absent on rows that have never been archived. ' isDeleted: type: boolean default: false description: Whether this conversation has been soft-deleted. deletedBy: type: string format: objectId description: User who soft-deleted this conversation. conversationErrors: type: array description: Errors recorded against this conversation (e.g. failed message generations). items: type: object required: - message properties: message: type: string errorType: type: string timestamp: type: string format: date-time messageId: type: string format: objectId stack: type: string metadata: type: object additionalProperties: true metadata: type: object additionalProperties: true description: Free-form metadata attached to the conversation. lastActivityAt: type: integer description: Unix timestamp of last activity createdAt: type: string format: date-time updatedAt: type: string format: date-time isOwner: type: boolean description: 'Computed per request. `true` when the requesting user is the conversation''s `initiator`. ' readOnly: true accessLevel: type: string enum: - read - write description: 'Computed per request. The requester''s effective access level: their entry in `sharedWith`, or `read` by default. ' readOnly: true projectId: type: - string - 'null' format: objectId description: 'The project this conversation is linked to, if any. Set via `PUT /conversations/{conversationId}/project` or at creation time; absent on conversations that were never linked. ' projectVisibility: type: - string - 'null' enum: - private - project description: 'Only meaningful when `projectId` is set. `private` (default) keeps the conversation visible to its owner only; `project` exposes it to every member of the linked project. See `PATCH /conversations/{conversationId}/project-visibility`. ' sharedBy: $ref: '#/components/schemas/ConversationSharedBy' MessageFeedback: type: object additionalProperties: false description: 'Comprehensive feedback on an AI response. Feedback helps improve the AI''s performance and response quality over time. ' properties: isHelpful: type: boolean description: Overall helpfulness rating ratings: type: object additionalProperties: false properties: accuracy: type: integer minimum: 1 maximum: 5 description: How accurate was the information (1-5) relevance: type: integer minimum: 1 maximum: 5 description: How relevant was the response (1-5) completeness: type: integer minimum: 1 maximum: 5 description: How complete was the answer (1-5) clarity: type: integer minimum: 1 maximum: 5 description: How clear was the explanation (1-5) categories: type: array items: type: string enum: - incorrect_information - missing_information - irrelevant_information - unclear_explanation - poor_citations - excellent_answer - helpful_citations - well_explained - other description: Categories of issues or positive attributes identified comments: type: object additionalProperties: false properties: positive: type: string description: What was good about the response negative: type: string description: What could be improved suggestions: type: string description: Specific suggestions for improvement citationFeedback: type: array items: type: object additionalProperties: false properties: _id: type: string format: objectId description: Auto-generated sub-document identifier citationId: type: string format: objectId isRelevant: type: boolean relevanceScore: type: integer minimum: 1 maximum: 5 comment: type: string description: Feedback on individual citations followUpQuestionsHelpful: type: boolean description: Were the suggested follow-up questions helpful unusedFollowUpQuestions: type: array items: type: string description: Follow-up questions that were suggested but not used by the user source: type: string enum: - user - system - admin - auto default: user description: Origin of the feedback. Always present in responses (server applies the default `user`). feedbackProvider: type: string format: objectId description: User who submitted the feedback timestamp: type: integer format: int64 description: 'Time the feedback was created, stored as a Number (epoch milliseconds) with a server-side default of `Date.now`, so always present in responses. Not an ISO 8601 datetime. ' revisions: type: array description: Audit trail of edits to this feedback entry items: type: object additionalProperties: false properties: _id: type: string format: objectId description: Auto-generated sub-document identifier updatedFields: type: array items: type: string description: Names of feedback fields modified in this revision previousValues: type: object additionalProperties: true description: 'Map of previously-set values for the fields named in `updatedFields`, keyed by field name. Stored as a Mongoose Map of Mixed values. ' updatedBy: type: string format: objectId updatedAt: type: integer format: int64 description: Time the revision was recorded, as epoch milliseconds. metrics: type: object additionalProperties: false description: Optional telemetry captured alongside the feedback properties: timeToFeedback: type: number description: Time from response delivery to feedback submission userInteractionTime: type: number description: Total time the user spent reviewing the response feedbackSessionId: type: string userAgent: type: string platform: type: string ChatAttachmentUploadRef: type: object additionalProperties: false description: 'Concrete attachment metadata returned by `POST /conversations/attachments/upload` (or the equivalent agent route). ' required: - recordId - recordName - mimeType - extension - virtualRecordId properties: recordId: type: string minLength: 1 description: Server-assigned attachment record id. recordName: type: string minLength: 1 description: Original filename stored for the attachment. mimeType: type: string minLength: 1 description: MIME type of the uploaded file. extension: type: string minLength: 1 description: File extension derived by the backend. virtualRecordId: type: string minLength: 1 description: Synthetic record id used by the graph layer. parseMode: type: string minLength: 1 description: Backend-reported parsing mode used for the attachment (e.g. `pdfplumber`, `docling`, `csv_lightweight`). ocrMode: type: string minLength: 1 deprecated: true description: Deprecated alias for `parseMode`, kept for backward compatibility. Use `parseMode` instead. MessageToolCall: type: object additionalProperties: false description: One tool invocation recorded on a message turn. properties: toolName: type: string toolResult: {} ConversationStreamRequest: allOf: - $ref: '#/components/schemas/CreateConversationRequest' - type: object description: 'Request body for `POST /conversations/stream`. The public stream requires an explicit universal execution mode. ' required: - chatMode SSEEvent: type: object description: "Server-Sent Event envelope for streaming chat responses. AG-UI is\nthe sole wire protocol.\n\n`event` carries the AG-UI type name and `data` is a JSON-encoded\nobject that includes a `\"type\"` field matching `event`, plus\ntype-specific fields. Stable gateway-generated top-level outcomes:\n\n- `RUN_FINISHED` — `{ type, result }`; `result` carries the full\n persisted `conversation` and a `meta` block with `requestId`,\n `timestamp` and `duration`.\n- `RUN_ERROR` — `{ type, message, code? }`. The conversation row is\n marked FAILED before the stream closes.\n\nForwarded upstream lifecycle or child-run events may contain `runId`,\n`threadId`, and `parentRunId`. Gateway-generated root terminal events\ndo not. Clients should ignore unknown event names.\n" properties: event: type: string enum: - RUN_STARTED - RUN_FINISHED - RUN_ERROR - STEP_STARTED - STEP_FINISHED - TEXT_MESSAGE_START - TEXT_MESSAGE_CONTENT - TEXT_MESSAGE_END - REASONING_START - REASONING_MESSAGE_START - REASONING_MESSAGE_CONTENT - REASONING_MESSAGE_END - REASONING_END - TOOL_CALL_START - TOOL_CALL_ARGS - TOOL_CALL_END - TOOL_CALL_RESULT - STATE_DELTA - STATE_SNAPSHOT - CUSTOM - HEARTBEAT data: type: string description: 'JSON-encoded event payload. The decoded JSON includes a `"type"` field matching `event`, plus type-specific fields. Shape depends on `event`. ' ConversationMessageStreamSSEEvent: type: object description: "Server-Sent Event envelope for public follow-up streams using `agent`,\n`internal_search`, or `web_search` on an existing conversation. AG-UI\nis the sole wire protocol.\n\n`event` carries the AG-UI type name and `data` is a JSON-encoded\nobject that includes a `\"type\"` field matching `event`, plus\ntype-specific fields. Universal `agent` mode may emit step and nested\nchild-run events. Stable gateway-generated top-level outcomes:\n\n- `CUSTOM` (`name: \"conversation_created\"`) — fired once on\n connection.\n- `RUN_FINISHED` — fired once after the AI backend finishes.\n The gateway emits `{ type, result }`; `result` carries\n `{ conversation, recordsUsed, meta }`.\n `recordsUsed` is the count of citations attached to the new\n assistant message.\n- `RUN_ERROR` — fired when the stream fails. Carries a `message`\n and optional `code`; the conversation row is marked FAILED\n before close.\n\nForwarded upstream lifecycle or child-run events may contain `runId`,\n`threadId`, and `parentRunId`. Gateway-generated root terminal events\ndo not.\nClients should ignore unknown event names rather than treating them\nas errors.\n" properties: event: type: string enum: - RUN_STARTED - RUN_FINISHED - RUN_ERROR - STEP_STARTED - STEP_FINISHED - TEXT_MESSAGE_START - TEXT_MESSAGE_CONTENT - TEXT_MESSAGE_END - REASONING_START - REASONING_MESSAGE_START - REASONING_MESSAGE_CONTENT - REASONING_MESSAGE_END - REASONING_END - TOOL_CALL_START - TOOL_CALL_ARGS - TOOL_CALL_END - TOOL_CALL_RESULT - STATE_DELTA - STATE_SNAPSHOT - CUSTOM - HEARTBEAT data: type: string description: 'JSON-encoded event payload. The decoded JSON includes a `"type"` field matching `event`, plus type-specific fields. Shape depends on `event`. Forwarded lifecycle events may carry `runId`, `threadId`, and `parentRunId`. ' CreateConversationResponse: type: object additionalProperties: false description: 'Envelope returned by `POST /conversations/create`. Contains the persisted conversation (including the initial user message and the AI response) plus request metadata. ' required: - conversation - meta properties: conversation: $ref: '#/components/schemas/Conversation' meta: type: object additionalProperties: false required: - timestamp - duration properties: requestId: type: string description: 'Request correlation id. Omitted when upstream middleware did not set a request id on the context. ' timestamp: type: string format: date-time description: Server timestamp when the response was sent. duration: type: integer minimum: 0 description: Total handler duration in milliseconds. MessageFeedbackAppendEntry: type: object additionalProperties: false required: - feedbackProvider - timestamp - metrics description: 'The feedback entry just appended to the message. Echoes the fields supplied in the request plus server-stamped `feedbackProvider`, `timestamp`, and `metrics`. ' properties: isHelpful: type: boolean description: Echoed from the request when supplied. categories: type: array description: Echoed categories from the request. items: type: string enum: - incorrect_information - missing_information - irrelevant_information - unclear_explanation - poor_citations - excellent_answer - helpful_citations - well_explained - other comments: type: object additionalProperties: false description: Echoed free-text comments from the request. properties: positive: type: string negative: type: string feedbackProvider: type: string format: objectId description: User who submitted the feedback. Always present. timestamp: type: integer format: int64 description: 'Submission time as epoch milliseconds (not an ISO 8601 datetime). Always present. ' metrics: $ref: '#/components/schemas/MessageFeedbackAppendMetrics' MessageFeedbackSubmitRequest: type: object additionalProperties: false description: 'Gateway request body for submitting message feedback (Zod `feedbackBodySchema`). All fields are optional; an empty object is accepted. Matches the first-party chat UI payload shape. ' properties: isHelpful: type: boolean description: Overall helpfulness signal (thumbs up/down). categories: type: array description: Issue or positive categories that apply to the response. items: type: string enum: - incorrect_information - missing_information - irrelevant_information - unclear_explanation - poor_citations - excellent_answer - helpful_citations - well_explained - other comments: type: object additionalProperties: false description: Free-text comments grouped by sentiment. properties: positive: type: string description: What was good about the response. negative: type: string description: What could be improved. RegenerateRequest: type: object additionalProperties: false description: "Request body for regenerating an AI response. All fields are optional;\nwhen omitted the model selection and execution context from the\noriginal message are reused.\n\nSupported fields:\n- `filters` — optional `{ apps?, kb? }` filter object\n- `chatMode` — optional non-empty chat mode string\n- `modelKey`, `modelName`, `modelFriendlyName` —\n optional non-empty model override fields\n- `timezone` — optional non-empty client timezone string\n- `currentTime` — optional ISO 8601 / RFC 3339 datetime string with\n UTC `Z` or a numeric offset\n- `tools` — optional array of non-empty tool identifiers\n- `protocol` — optional inert compatibility field; when present it must\n be `agui`, which is also the protocol used when the field is omitted\n- `agentCapabilities` — optional per-request agent capability toggles\n" properties: filters: $ref: '#/components/schemas/Filters' modelKey: type: string minLength: 1 description: 'Identifier of the AI model configuration to use for regeneration. Typically a UUID returned by the model-management endpoints. When omitted, the model used for the original message is reused. ' example: 05438a37-68f2-4641-a8dc-6c47e63278ca modelName: type: string minLength: 1 description: Provider model name (e.g. the underlying LLM identifier). example: gpt-5.6-luna modelFriendlyName: type: string minLength: 1 description: Friendly display name of the selected model. example: mini chatMode: type: string minLength: 1 description: 'Chat mode used for regeneration (for example `internal_search`, `web_search`, or the universal `agent` mode). ' example: internal_search timezone: type: string minLength: 1 description: 'IANA timezone identifier from the client. Used to provide time-aware context to the AI during regeneration. ' example: Asia/Calcutta currentTime: type: string format: date-time description: 'ISO 8601 / RFC 3339 datetime from the client (UTC `Z` or numeric offset). Used to anchor any relative time references in the query. ' example: '2026-05-11T15:43:21+05:30' tools: type: array items: type: string minLength: 1 description: 'Optional list of tool identifiers (fully-qualified action names such as `jira.create_issue`) the agent may invoke when regenerating. Applicable only in agent chat modes. ' example: - jira.create_issue - confluence.search_content protocol: type: string enum: - agui description: 'AG-UI is the only supported wire protocol. When present must be `"agui"`. Omitting the field is equivalent — the server always uses the AG-UI vocabulary. Kept in the schema for backward compatibility with callers that already send it. ' agentCapabilities: $ref: '#/components/schemas/AgentCapabilities' runId: type: string format: uuid description: 'Client-generated identifier for this regeneration run. Send it here to enable `POST .../cancel {runId}` while it is still generating. ' AddMessageRequest: type: object description: Request body for adding a message to an existing conversation required: - query properties: query: type: string minLength: 1 description: The follow-up question or message content example: Can you elaborate on the revenue trends? filters: $ref: '#/components/schemas/Filters' appliedFilters: $ref: '#/components/schemas/AppliedFilters' attachments: type: array items: $ref: '#/components/schemas/ChatAttachmentRef' description: 'Uploaded chat attachments for this follow-up turn (see `POST /conversations/attachments/upload`). ' modelKey: type: string description: Override the model for this specific message modelName: type: string description: Display name of the model modelFriendlyName: type: string description: Friendly display name of the model chatMode: type: string enum: - agent - internal_search - web_search description: 'Optional execution mode for non-stream consumers of this shared request schema. ' timezone: type: string minLength: 1 description: 'IANA timezone identifier from the client (top-level field). Used to provide time-aware context to the AI. ' example: America/New_York currentTime: type: string format: date-time description: 'ISO 8601 / RFC 3339 datetime from the client (top-level field; UTC `Z` or numeric offset). ' example: '2026-04-12T16:00:00+05:30' tools: type: array items: type: string minLength: 1 description: 'Optional list of tool identifiers the agent may invoke for this follow-up message. Semantics are identical to the create-conversation tools field. ' example: - jira.create_issue - confluence.search_content protocol: type: string enum: - agui description: 'AG-UI is the only supported wire protocol. When present must be `"agui"`. Omitting the field is equivalent — the server always uses the AG-UI vocabulary (see `ConversationMessageStreamSSEEvent`). Kept in the schema for backward compatibility with callers that already send it. ' agentCapabilities: $ref: '#/components/schemas/AgentCapabilities' runId: type: string format: uuid description: 'Client-generated identifier for this run. Send it here to enable `POST /conversations/{conversationId}/cancel {runId}` while the stream is still generating. ' ConversationMessageStreamRequest: allOf: - $ref: '#/components/schemas/AddMessageRequest' - type: object description: 'Request body for `POST /conversations/{conversationId}/messages/stream`. The public stream requires an explicit universal execution mode. ' required: - chatMode Citation: type: object additionalProperties: false description: 'A populated citation document. Represents a single chunk of source content (e.g. a passage from a document or record) referenced by an AI response, together with its provenance metadata. ' required: - _id - content - chunkIndex - citationType - metadata - createdAt - updatedAt properties: _id: type: string format: objectId content: type: string description: The cited text chunk chunkIndex: type: integer description: Index of this chunk within the source record citationType: type: string description: Source type identifier (e.g. `vectordb|document`) metadata: $ref: '#/components/schemas/PersistedSemanticSearchCitationMetadata' createdAt: type: string format: date-time updatedAt: type: string format: date-time PopulatedCitationReference: type: object additionalProperties: false description: 'A message''s citation reference after the handler populates it: the stored reference fields, with `citationId` as the id and the cited document under `citationData`. ' properties: citationId: type: string format: objectId description: ID of the citation record relevanceScore: type: number minimum: 0 maximum: 1 description: How relevant this citation is to the query (0-1) excerpt: type: string description: Relevant excerpt from the source document context: type: string description: Additional context around the citation citationData: $ref: '#/components/schemas/Citation' AppliedFilters: type: object additionalProperties: false description: 'Rich filter state selected by the user, used for display and persistence only. This mirrors the active selection shown in the UI and is distinct from the machine-readable `filters` field used for retrieval scoping. ' properties: apps: type: array items: $ref: '#/components/schemas/AppliedFilterNode' description: Applied app/connector filter nodes kb: type: array items: $ref: '#/components/schemas/AppliedFilterNode' description: Applied knowledge-base filter nodes ConversationModelInfo: type: object additionalProperties: false description: AI model configuration recorded against a conversation or message. properties: modelKey: type: string description: Stable identifier of the configured model record modelName: type: string description: Provider-facing model name (e.g. `gpt-5.6-luna`) modelProvider: type: string description: Provider key (e.g. `openai`, `anthropic`) modelFriendlyName: type: string description: Human-readable display name chatMode: type: string description: Chat mode used for this turn (e.g. `quick`, `internal_search`) PersistedSemanticSearchCitationMetadata: type: object additionalProperties: false description: 'Citation metadata as persisted in MongoDB. Required fields mirror the Mongoose schema''s `required: true` flags; the rest are optional and may come through as `null` because the AI retrieval service emits explicit nulls for absent fields. ' required: - orgId - mimeType - recordId - recordName - origin properties: orgId: type: string mimeType: type: string recordId: type: string recordName: type: string origin: type: string recordVersion: type: - integer - 'null' extension: type: - string - 'null' webUrl: type: - string - 'null' previewRenderable: type: - boolean - 'null' hideWeburl: type: - boolean - 'null' connector: type: - string - 'null' connectorId: type: - string - 'null' description: 'The connector instance the record came from. `connector` names only the kind of source (for example `SLACK`), which several instances can share. Absent on citations saved before this field was stored. ' recordType: type: - string - 'null' blockNum: type: - array - 'null' items: type: - number - 'null' pageNum: type: - array - 'null' items: type: - number - 'null' sheetNum: type: - number - 'null' sheetName: type: - string - 'null' bounding_box: type: - array - 'null' items: $ref: '#/components/schemas/PersistedSemanticSearchBoundingBox' blockType: type: - string - 'null' description: 'Block type for this citation. Common values: `text`, `image`, `table_row`, `table`, `record_summary` (whole-record semantic summary chunk). ' blockText: type: - string - 'null' departments: type: - array - 'null' items: type: string languages: type: - array - 'null' items: type: string topics: type: - array - 'null' items: type: string ConversationSharedBy: type: object additionalProperties: false description: 'Present on conversations the caller received via share. Identifies the conversation initiator (the only user who can share a chat). ' required: - userId - name properties: userId: type: string format: objectId name: type: string description: Display name, falling back to email or the user id MessagePart: type: object additionalProperties: false description: 'One entry in the ordered agent-activity transcript for a message turn. Every field beyond `type` is optional and depends on the part kind, and `sub_agent` nests this same shape recursively under `parts`. Tool results here are always a bounded preview, never the full payload — `artifactId` points at the complete result. ' properties: type: type: string enum: - text - reasoning - tool_call - sub_agent content: type: string toolCallId: type: string toolName: type: string displayName: type: string args: type: string argsSummary: type: string description: Human-readable summary of `args`, computed server-side. status: type: string enum: - running - completed - failed - blocked resultPreview: type: string resultSummary: type: string description: 'Human-readable summary of the tool result, computed server-side from the full untruncated output. ' artifactId: type: string description: Blob-backed artifact id for the full tool result. runId: type: string roleName: type: string isFinal: type: boolean description: 'Set on the single root-level `text` part carrying the answer. Every other root `text` part is an abandoned preamble turn. Never set on child parts nested under a `sub_agent`. ' parts: type: array description: Nested transcript of a `sub_agent` part. items: $ref: '#/components/schemas/MessagePart' ChatAttachmentUploadResponse: type: object additionalProperties: false description: 'Success envelope returned by `POST /conversations/attachments/upload` and `POST /agents/{agentKey}/conversations/attachments/upload`. ' required: - conversationId - attachments properties: conversationId: type: - string - 'null' description: 'Existing conversation id echoed from the request when the upload is tied to a thread; otherwise `null`. ' attachments: type: array minItems: 1 items: $ref: '#/components/schemas/ChatAttachmentUploadRef' MessageFeedbackAppendMetrics: type: object additionalProperties: false required: - timeToFeedback description: 'Telemetry recorded server-side alongside the feedback. Always present on append responses. ' properties: timeToFeedback: type: number description: 'Milliseconds between message creation and feedback submission. Always present. ' userAgent: type: string description: Value of the `User-Agent` request header captured server-side. ConversationListItem: type: object description: 'Conversation summary returned by list endpoints. Identical to `Conversation` but omits `messages` to keep list payloads small. Fetch a single conversation to retrieve its messages. ' properties: _id: type: string format: objectId userId: type: string format: objectId orgId: type: string format: objectId title: type: string initiator: type: string format: objectId status: type: string enum: - None - Inprogress - Complete - Failed - Stopped failReason: type: string modelInfo: type: object properties: modelKey: type: string modelName: type: string modelFriendlyName: type: string modelProvider: type: string chatMode: type: string isShared: type: boolean shareLink: type: string sharedWith: type: array items: type: object properties: userId: type: string format: objectId accessLevel: type: string enum: - read - write isArchived: type: boolean archivedBy: type: - string - 'null' format: objectId description: 'User ID of the last user who archived this row, or `null` after unarchive cleared the archive state. Absent on rows that have never been archived. ' isDeleted: type: boolean deletedBy: type: string format: objectId conversationErrors: type: array items: type: object properties: message: type: string errorType: type: string timestamp: type: string format: date-time messageId: type: string format: objectId stack: type: string metadata: type: object additionalProperties: true metadata: type: object additionalProperties: true lastActivityAt: type: integer createdAt: type: string format: date-time updatedAt: type: string format: date-time isOwner: type: boolean readOnly: true accessLevel: type: string enum: - read - write readOnly: true projectId: type: - string - 'null' format: objectId description: 'The project this conversation is linked to, if any. Set via `PUT /conversations/{conversationId}/project` or at creation time; absent on conversations that were never linked. ' projectVisibility: type: - string - 'null' enum: - private - project description: 'Only meaningful when `projectId` is set. `private` (default) keeps the conversation visible to its owner only; `project` exposes it to every member of the linked project. See `PATCH /conversations/{conversationId}/project-visibility`. ' sharedBy: $ref: '#/components/schemas/ConversationSharedBy' MessageFeedbackUpdateResponse: type: object additionalProperties: false required: - conversationId - messageId - feedback - meta description: 'Gateway response after appending feedback to a bot-response message. ' properties: conversationId: type: string format: objectId description: Conversation the feedback was attached to. messageId: type: string format: objectId description: Message the feedback was attached to. feedback: $ref: '#/components/schemas/MessageFeedbackAppendEntry' meta: type: object additionalProperties: false required: - requestId - timestamp - duration properties: requestId: type: string description: 'Server-side request identifier. Read from the `X-Request-ID` header when supplied, otherwise auto-generated, so this field is always present. ' timestamp: type: string format: date-time duration: type: integer description: Server-side processing time in milliseconds. PersistedSemanticSearchBoundingBox: type: object additionalProperties: false description: 'Bounding box subdocument embedded in persisted citation metadata. `boundingBoxSchema` does not set `_id: false`, so Mongoose auto-injects an `_id`. ' required: - _id - x - y properties: _id: type: string format: objectId x: type: number y: type: number headers: X-Conversation-Id: description: 'Id of the conversation this turn wrote to. Sent on success and on failure, so a caller whose first turn failed can still fetch or continue that conversation. ' schema: type: string format: objectId securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'JWT Bearer token for authenticated requests. A personal access token (see the **Personal Access Tokens** tag) is a `phpat_`-prefixed variant of this same JWT — e.g. `phpat_eyJhbGci...`. The prefix is display-only, added for secret-scanner detectability; the gateway strips it before verifying the token, so send it exactly as issued, prefix included. ' scopedToken: type: http scheme: bearer bearerFormat: JWT description: 'Scoped JWT token for service-to-service authentication. Format: "Bearer {scoped_token}" Required scopes vary by endpoint. ' oauth2: type: oauth2 description: 'OAuth 2.0 authentication with fine-grained scopes. Supports authorization_code (with PKCE) and client_credentials flows. OAuth tokens are Bearer JWTs — use the same Authorization header as regular tokens. For **client_credentials**, machine JWTs may use `userId === client_id`; the Node gateway resolves the OAuth app creator — see **OAuth Provider** tag. ' flows: authorizationCode: authorizationUrl: /api/v1/oauth2/authorize tokenUrl: /api/v1/oauth2/token refreshUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:read: Read semantic search results and history semantic:write: Execute semantic search semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs crawl:delete: Delete crawling jobs clientCredentials: tokenUrl: /api/v1/oauth2/token scopes: openid: OpenID Connect authentication profile: User profile information email: User email address offline_access: Offline access (refresh tokens) org:read: Read organization information org:write: Update organization settings org:admin: Full organization administration user:read: Read user profiles user:write: Update user profiles user:invite: Invite new users user:delete: Delete users usergroup:read: Read user groups usergroup:write: Create and manage user groups team:read: Read team information team:write: Create and manage teams kb:read: Read knowledge bases and records kb:write: Create and update knowledge bases kb:delete: Delete knowledge bases and records kb:upload: Upload files to knowledge bases semantic:write: Execute semantic search semantic:read: Read semantic search results and history semantic:delete: Delete semantic search history conversation:read: Read conversations conversation:write: Create and manage conversations conversation:chat: Send messages in conversations project:read: Read projects and their conversations project:write: Create and manage projects project:delete: Delete projects agent:read: Read AI agents agent:write: Create and manage AI agents agent:execute: Execute AI agents connector:read: Read connector configurations connector:write: Create and update connectors connector:sync: Trigger connector synchronization connector:delete: Delete connectors config:read: Read system configuration config:write: Update system configuration crawl:read: Read crawling jobs crawl:write: Create and manage crawling jobs x-refined-from: - pipeshub-openapi.yaml - pipeshub-openapi.yml