Netcracker AI Chat API

APIs for AI chat assistant. Each user has their own chat list; chats are persisted on the server with a configurable TTL and pinning support. Conversations support streaming responses (SSE) and automatic context compaction (old messages are re-packed into a summary when the conversation approaches the model's context window, so that older facts are preserved instead of being silently dropped by the LLM).

Operations 8

GET /api/v1/ai-chat/chats List chats of the current user. #
POST /api/v1/ai-chat/chats Create a new chat. #
GET /api/v1/ai-chat/chats/{chatId} Get chat metadata. #
PATCH /api/v1/ai-chat/chats/{chatId} Update chat (rename / pin / unpin). #
DELETE /api/v1/ai-chat/chats/{chatId} Delete a chat. #
GET /api/v1/ai-chat/chats/{chatId}/messages List chat messages. #
POST /api/v1/ai-chat/chats/{chatId}/messages Send a message (non-streaming). #
POST /api/v1/ai-chat/chats/{chatId}/messages/stream Send a message with streaming response (SSE). #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/netcracker-ai-chat-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

netcracker-ai-chat-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: APIHUB Registry – External AI Chat API
  description: 'Public-facing API contract for APIHUB. This API is intended for external and integration clients and covers package/catalog operations, publication workflows, search, user/profile actions, and selected administration capabilities secured by APIHUB authentication schemes.

    '
  contact:
    name: Netcracker Opensource Group
    email: opensourcegroup@netcracker.com
  license:
    name: Apache-2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  version: '2026.1'
  x-api-kind: BWC
servers:
- url: https://{apihub}.qubership.org
  description: Primary APIHUB server endpoint (use the apihub variable to select production, development, or staging).
  variables:
    apihub:
      description: APIHUB subdomain/environment selector (apihub=production, dev.apihub=development, staging.apihub=staging).
      enum:
      - apihub
      - dev.apihub
      - staging.apihub
      default: apihub
security:
- BearerAuth: []
- CookieAuth: []
- api-key: []
- PersonalAccessToken: []
tags:
- name: AI Chat
  description: 'APIs for AI chat assistant.

    Each user has their own chat list; chats are persisted on the server with a configurable TTL and pinning support.

    Conversations support streaming responses (SSE) and automatic context compaction (old messages are re-packed into a summary when the conversation approaches the model''s context window, so that older facts are preserved instead of being silently dropped by the LLM).

    '
paths:
  /api/v1/ai-chat/chats:
    get:
      tags:
      - AI Chat
      summary: List chats of the current user.
      description: 'Returns chat metadata (without messages) for the authenticated user, sorted first by `pinned` desc, then by `lastMessageAt` desc.

        Chats of other users are never returned.


        Pagination is keyset-based rather than page-based because a user''s chat list is a live view: pinning/unpinning and incoming messages constantly reorder entries, so a second offset-based request would produce duplicates or gaps. A timestamp cursor (`before`) is stable under these changes.


        Usage: the first request omits `before` and receives the newest `limit` chats; subsequent requests pass `before` = `lastMessageAt` of the last (oldest) chat from the previous page. The client never generates the timestamp itself, so no client/server clock-skew handling is required.

        '
      operationId: listAiChats
      parameters:
      - name: limit
        in: query
        description: Maximum number of chats to return. Server may cap this value.
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 100
      - name: before
        in: query
        description: 'Keyset cursor. Return only chats with `lastMessageAt` strictly less than this value. Format: RFC 3339 timestamp.

          When omitted, the server returns the newest `limit` chats (i.e. the first page).

          Pinned chats are always returned before non-pinned chats regardless of the cursor.

          '
        required: false
        schema:
          type: string
          format: date-time
          example: '2026-04-18T09:12:33Z'
      - name: search
        in: query
        description: Optional case-insensitive substring match on chat `title`.
        required: false
        schema:
          type: string
      responses:
        '200':
          description: Successful execution
          content:
            application/json:
              schema:
                type: object
                required:
                - chats
                properties:
                  chats:
                    type: array
                    items:
                      $ref: '#/components/schemas/AiChat'
                  hasMore:
                    description: True if more chats are available with an earlier `lastMessageAt`.
                    type: boolean
              examples:
                AiChatsList:
                  $ref: '#/components/examples/AiChatsList'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
    post:
      tags:
      - AI Chat
      summary: Create a new chat.
      description: 'Creates an empty chat owned by the authenticated user.

        The title is optional and will be filled automatically (from the first user message) if omitted; it can be changed later via PATCH.

        '
      operationId: createAiChat
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AiChatCreateRequest'
      responses:
        '201':
          description: Chat created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiChat'
              examples:
                AiChat:
                  $ref: '#/components/examples/AiChat'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                IncorrectInputParams:
                  $ref: '#/components/examples/IncorrectInputParameters'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
  /api/v1/ai-chat/chats/{chatId}:
    parameters:
    - $ref: '#/components/parameters/chatId'
    get:
      tags:
      - AI Chat
      summary: Get chat metadata.
      description: 'Returns the metadata of a chat owned by the current user.

        The response does not contain messages — use `GET /api/v1/ai-chat/chats/{chatId}/messages` to retrieve them.

        '
      operationId: getAiChat
      responses:
        '200':
          description: Successful execution
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiChat'
              examples:
                AiChat:
                  $ref: '#/components/examples/AiChat'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
    patch:
      tags:
      - AI Chat
      summary: Update chat (rename / pin / unpin).
      description: "Partially updates a chat. Only the fields present in the request body are updated.\nPinning rules:\n  * a user may pin at most **3** chats (the limit is hard-coded identically on the client and on the server); pinning beyond the limit returns `400`;\n  * pinned chats are exempt from TTL-based cleanup.\n"
      operationId: updateAiChat
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AiChatUpdateRequest'
      responses:
        '200':
          description: Chat updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiChat'
        '400':
          description: "Bad request. Typical reasons:\n  * attempting to pin when the user already has the maximum allowed number of pinned chats;\n  * `title` too long or empty after trimming.\n"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                PinLimitExceeded:
                  $ref: '#/components/examples/AiChatPinLimitExceeded'
                AiChatValidationFailed:
                  $ref: '#/components/examples/AiChatValidationFailed'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
    delete:
      tags:
      - AI Chat
      summary: Delete a chat.
      description: 'Permanently deletes a chat together with all its messages. Any generated files referenced by its messages remain available on disk until their file-level TTL expires.

        '
      operationId: deleteAiChat
      responses:
        '204':
          description: Chat deleted
          content: {}
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
  /api/v1/ai-chat/chats/{chatId}/messages:
    parameters:
    - $ref: '#/components/parameters/chatId'
    get:
      tags:
      - AI Chat
      summary: List chat messages.
      description: "Returns messages of the given chat in reverse-chronological order (newest first). Use keyset pagination via `before` to fetch older pages.\n\nKeyset pagination is used (rather than `page`) because messages are appended live: a naive offset would miss or duplicate items whenever a new message arrives between two page fetches. The first request omits `before` and receives the newest `limit` messages; subsequent requests pass `before` = `createdAt` of the last (oldest) message from the previous page.\n\nFor every `assistant` message the response includes:\n  * full markdown `content` (same that was streamed) — including any inline markdown links to generated files, with freshly re-issued signed tokens so the links remain usable for the standard file TTL at the moment of the request;\n  * `toolInvocations` — UI-facing summaries (tool name, status, duration) that were shown as transient pills during the live stream, so that after a reload the user still sees which tools were used. Clients that do not need this telemetry may ignore the field.\n\nWhat is intentionally not returned:\n  * raw LLM tool-call arguments and tool results (internal; not needed for rendering);\n  * system prompt and compaction summaries (internal context-management artefacts).\n\nThis endpoint is the only way to load history — the streaming endpoint is strictly for producing new turns, not for replaying existing ones.\n"
      operationId: listAiChatMessages
      parameters:
      - name: limit
        in: query
        required: false
        description: Maximum number of messages to return.
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 100
      - name: before
        in: query
        required: false
        description: 'Keyset cursor. Return only messages created strictly before this timestamp (RFC 3339).

          When omitted, the server returns the newest `limit` messages (i.e. the first page).

          '
        schema:
          type: string
          format: date-time
      responses:
        '200':
          description: Successful execution
          content:
            application/json:
              schema:
                type: object
                required:
                - messages
                properties:
                  messages:
                    type: array
                    description: Messages in reverse-chronological order (newest first).
                    items:
                      $ref: '#/components/schemas/AiChatMessage'
                  hasMore:
                    description: True if more messages are available before the oldest returned one.
                    type: boolean
              examples:
                AiChatMessagesList:
                  $ref: '#/components/examples/AiChatMessagesList'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
    post:
      tags:
      - AI Chat
      summary: Send a message (non-streaming).
      description: 'Appends a user message to the chat and waits synchronously for the assistant response.

        Intended for integration scripts or clients that do not want to handle SSE. Interactive UIs should use the streaming variant (`/messages/stream`) instead.

        The request body must carry **only the new user message** — never the full history. The server reconstructs the conversation context from its own storage (including any compaction summary) and sends the resulting message list to the LLM on each turn.

        '
      operationId: sendAiChatMessage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AiChatSendMessageRequest'
      responses:
        '200':
          description: Assistant response produced
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AiChatSendMessageResponse'
              examples:
                AiChatSendMessageResponse:
                  $ref: '#/components/examples/AiChatSendMessageResponse'
        '400':
          description: Bad request (empty content, invalid clientMessageId, etc.).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatValidationFailed:
                  $ref: '#/components/examples/AiChatValidationFailed'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
  /api/v1/ai-chat/chats/{chatId}/messages/stream:
    parameters:
    - $ref: '#/components/parameters/chatId'
    post:
      tags:
      - AI Chat
      summary: Send a message with streaming response (SSE).
      description: "Appends a user message to the chat and streams the assistant response as Server-Sent Events.\n\nRequest semantics:\n  * the body carries **only the new user message** plus (optionally) a client-generated `clientMessageId` for idempotency — never the full conversation history;\n  * the server reconstructs context from its own storage (including any compaction summary) and sends the resulting message list to the LLM on each turn — the client never transmits prior turns;\n  * on the very first message in a chat the server may auto-fill the chat title in the background.\n\nResponse semantics (SSE):\n  * `Content-Type: text/event-stream; charset=utf-8`;\n  * each event is framed as `event: <type>\\n` + `data: <json>\\n\\n`;\n  * the connection is closed by the server after emitting a terminal event (`done` or `error`);\n  * to cancel a turn the client may abort the underlying HTTP request; the server will stop the upstream LLM call best-effort but the partial assistant message that was already persisted stays in the history.\n\nPossible event types (in order of occurrence):\n  * `context.compacted` — emitted at most once per turn, before the assistant starts streaming, when the server auto-compacted earlier history into a summary;\n  * `message.assistant.start` — assistant message created; contains its `id`;\n  * `tool.started` — MCP tool call has started (UI hint: \"Searching API operations…\");\n  * `tool.completed` — MCP tool call finished (`ok: true/false`, duration);\n  * `message.assistant.delta` — incremental markdown chunk to append; chunks are safe to concatenate as-is;\n  * `message.assistant.completed` — full final markdown of the assistant message, including any inline markdown links to generated files;\n  * `error` — unrecoverable error; stream ends;\n  * `done` — terminal marker; stream ends.\n\nEvery event payload is a JSON object; see `AiChatStreamEvent` schemas for details.\n"
      operationId: sendAiChatMessageStream
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AiChatSendMessageRequest'
      responses:
        '200':
          description: 'Streaming response. The body is a sequence of SSE events, not a single JSON object.

            The schema below is provided for documentation only: each `data:` payload conforms to `AiChatStreamEvent`.

            '
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/AiChatStreamEvent'
              examples:
                AiChatStreamEvents:
                  $ref: '#/components/examples/AiChatStreamEvents'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatValidationFailed:
                  $ref: '#/components/examples/AiChatValidationFailed'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                Unauthorized:
                  $ref: '#/components/examples/Unauthorized'
        '404':
          description: Chat not found or does not belong to the current user.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                AiChatNotFound:
                  $ref: '#/components/examples/AiChatNotFound'
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                InternalServerError:
                  $ref: '#/components/examples/InternalServerError'
components:
  examples:
    Unauthorized:
      description: Unauthorized access
      value:
        status: 401
        code: APIHUB-4101
        message: Authentication required
    AiChatNotFound:
      description: Chat not found by id. Response for the 404 error.
      value:
        status: 404
        code: APIHUB-AI-3001
        message: chat with chatId = $chatId not found
    InternalServerError:
      description: 'Example: default internal server error response'
      value:
        status: 500
        code: APIHUB-8000
        reason: InternalServerError
        message: InternalServerError
    AiChatValidationFailed:
      description: AI chat request validation failed (empty content, message too long, invalid cursor, malformed JSON body, etc.).
      value:
        status: 400
        code: APIHUB-AI-4001
        message: Message exceeds maximum length of 32000 characters
        params:
          max: 32000
    AiChatsList:
      description: A page of the user's chats
      value:
        chats:
        - chatId: a1111111-1111-1111-1111-111111111111
          title: 'Pinned: release checklist'
          pinned: true
          createdAt: '2026-04-01T07:00:00Z'
          lastMessageAt: '2026-04-19T10:22:01Z'
          messagesCount: 18
        - chatId: e1a9f6d2-4a17-4a3b-9b91-4d7e9e8a0f11
          title: How do I paginate REST operations?
          createdAt: '2026-04-12T08:01:07Z'
          lastMessageAt: '2026-04-19T15:44:12Z'
          messagesCount: 42
        hasMore: true
    AiChatStreamEvents:
      summary: Full SSE turn — context compaction + tool call + delta chunks + done
      description: 'Example of a full SSE response body. Each event is framed as `event: <type>\ndata: <json>\n\n`.


        ```

        event: context.compacted

        data: {"type":"context.compacted","compactedUpTo":"2026-04-19T15:40:00Z","summaryPreview":"The user asked about REST operations in package QS.QSS.PRG.APIHUB…","messagesBefore":48,"messagesKeptRaw":8}


        event: message.assistant.start

        data: {"type":"message.assistant.start","messageId":"2f5a8c6b-8c11-4b1a-9c6a-1c2e4d5f6a7b"}


        event: tool.started

        data: {"type":"tool.started","toolCallId":"call_1","name":"search_rest_api_operations"}


        event: tool.completed

        data: {"type":"tool.completed","toolCallId":"call_1","name":"search_rest_api_operations","status":"ok","durationMs":312}


        event: message.assistant.delta

        data: {"type":"message.assistant.delta","delta":"Here are the operations I found:\n\n"}


        event: message.assistant.completed

        data: {"type":"message.assistant.completed","message":{"messageId":"2f5a8c6b-8c11-4b1a-9c6a-1c2e4d5f6a7b","role":"assistant","content":"Here are the operations I found:\n\n","createdAt":"2026-04-19T15:44:12Z","toolInvocations":[{"name":"search_rest_api_operations","status":"ok","durationMs":312}]}}


        event: done

        data: {"type":"done"}

        ```

        '
      value:
        type: done
    IncorrectInputParameters:
      description: Incorrect input parameters
      value:
        status: 400
        code: APIHUB-COMMON-4001
        message: Incorrect input parameters
    AiChatPinLimitExceeded:
      description: User attempts to pin more chats than allowed.
      value:
        status: 400
        code: APIHUB-AI-4003
        message: 'Cannot pin chat: user already has 3 pinned chats (the limit is 3)'
    AiChatMessagesList:
      description: Last page of messages in a chat (newest first).
      value:
        messages:
        - messageId: 2f5a8c6b-8c11-4b1a-9c6a-1c2e4d5f6a7b
          role: assistant
          content: 'Here are the operations I found:


            | Operation | Method | Path |

            | --- | --- | --- |

            | [get-packages-list](/portal/packages/QS.QSS.PRG.APIHUB/2026.1/operations/rest/get-packages-list) | GET | /api/v2/packages |


            And a CSV export: [operations-report.csv](/api/v1/ephemeral-files/7b6f4f87-4c8f-4d69-a66e-4a3c8a1b2c55?token=eyJhbGciOi...)

            '
          createdAt: '2026-04-19T15:44:12Z'
          toolInvocations:
          - name: search_rest_api_operations
            status: ok
            durationMs: 312
        - messageId: 1a0bcd12-0000-4000-8000-000000000001
          clientMessageId: 9c8e9045-dd9c-4946-b9e4-e05e3f41c4cc
          role: user
          content: List all REST operations in package QS.QSS.PRG.APIHUB.
          createdAt: '2026-04-19T15:44:03Z'
        hasMore: true
    AiChat:
      description: Single chat metadata
      value:
        chatId: e1a9f6d2-4a17-4a3b-9b91-4d7e9e8a0f11
        title: How do I paginate REST operations?
        createdAt: '2026-04-12T08:01:07Z'
        lastMessageAt: '2026-04-19T15:44:12Z'
        messagesCount: 42
    AiChatSendMessageResponse:
      description: Non-streaming response after a user message has been answered.
      value:
        userMessage:
          messageId: 1a0bcd12-0000-4000-8000-000000000001
          clientMessageId: 9c8e9045-dd9c-4946-b9e4-e05e3f41c4cc
          role: user
          content: List all REST operations in package QS.QSS.PRG.APIHUB.
          createdAt: '2026-04-19T15:44:03Z'
        assistantMessage:
          messageId: 2f5a8c6b-8c11-4b1a-9c6a-1c2e4d5f6a7b
          role: assistant
          content: Here are the operations I found...
          createdAt: '2026-04-19T15:44:12Z'
          toolInvocations:
          - name: search_rest_api_operations
            status: ok
            durationMs: 312
  schemas:
    AiChatCreateRequest:
      description: Optional payload for creating a new chat.
      type: object
      properties:
        title:
          description: Explicit chat title. If omitted, the title will be derived from the first user message.
          type: string
          maxLength: 120
          example: Playground checklist
    AiChatSendMessageResponse:
      description: Non-streaming response after a user message has been processed.
      type: object
      required:
      - userMessage
      - assistantMessage
      properties:
        userMessage:
          $ref: '#/components/schemas/AiChatMessage'
        assistantMessage:
          $ref: '#/components/schemas/AiChatMessage'
    AiChatStreamAssistantCompletedEvent:
      description: Terminal event for the assistant message. Carries the full final markdown (including any inline links to generated files).
      type: object
      required:
      - type
      - message
      properties:
        type:
          type: string
          enum:
          - message.assistant.completed
        message:
          $ref: '#/components/schemas/AiChatMessage'
    AiChatToolInvocation:
      description: 'Minimal, UI-facing descriptor of an MCP tool call that happened while producing an assistant message. The server intentionally does not expose tool arguments or raw results in order to keep the contract stable and avoid leaking internal data.

        '
      type: object
      required:
      - name
      - status
      properties:
        name:
          description: MCP tool name (e.g. `search_rest_api_operations`).
          type: string
          example: search_rest_api_operations
        status:
          description: Final status of the tool invocation.
          type: string
          enum:
          - ok
          - error
        durationMs:
          description: Wall-clock execution time in milliseconds.
          type: integer
          minimum: 0
          example: 312
    AiChatStreamToolStartedEvent:
      description: 'Emitted when the assistant decides to call an MCP tool. Multiple tool events may appear between `message.assistant.start` and `message.assistant.completed`.

        '
      type: object
      required:
      - type
      - toolCallId
      - name
      properties:
        type:
          type: string
          enum:
          - tool.started
        toolCallId:
          description: Opaque identifier correlating `tool.started` with `tool.completed`.
          type: string
          example: call_1a2b3c
        name:
          type: string
          example: search_rest_api_operations
    AiChatStreamDoneEvent:
      description: Terminal marker. Always the last event on a successful stream.
      type: object
      required:
      - type
      properties:
        type:
          type: string
          enum:
          - done
    ErrorResponse:
      description: Standard error response returned for failed requests. Includes HTTP status, internal error code, human-readable message, optional message parameters, and optional debug details (non-production only).
      type: object
      properties:
        status:
          description: HTTP status code as an integer; expected to match the actual HTTP response status.
          type: number
        code:
          description: Internal string error code. Mandatory in response.
          type: string
        message:
          description: Human-readable error message describing what went wrong; intended for diagnostics and safe client display.
          type: string
        params:
          type: object
          description: Optional key/value parameters used to format or contextualize the error message (for example, identifiers or field names).
          example:
            id: 12345
            type: string
        debug:
          description: Optional debug details (for example, stack traces). Returned only in development/test environments when verbose logging is enabled; do not rely on this field in production because it may contain sensitive data.
          type: string
      required:
      - status
      - code
      - message
    AiChatUpdateRequest:
      description: 'Partial update of a chat. Only fields present in the request are modified. At least one field must be supplied.

        '
      type: object
      minProperties: 1
      properties:
        title:
          description: New title for the chat.
          type: string
          minLength: 1
          maxLength: 120
          example: Tenant-aware search questions
        pinned:
          description: 'If true, pins the chat. Pinning is rejected with `400` when the user 

# --- truncated at 32 KB (43 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/netcracker/refs/heads/main/openapi/netcracker-ai-chat-api-openapi.yml