Clear Street Omni AI API

Thread-centric AI assistant for conversational trading. Create threads to start conversations, poll response objects for in-progress output, and read finalized messages from thread history. Thread/message/response endpoints require an explicit account_id. Entitlement endpoints are caller-scoped and use account_ids.

OpenAPI Specification

clear-street-omni-ai-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Clear Street Trading Omni AI API
  description: 'A unified, secure, and high-performance RESTful API for all client interactions with the Active trading platform.

    This specification provides a single source of truth for the API surface, covering order management, trade execution, market data, and account services.


    ### Authentication

    All endpoints require authentication via a JWT Bearer token provided in the `Authorization` header.


    ### Response Structure

    All responses, both for success and error, adhere to a standard envelope structure:

    - `data`: Contains the response payload on success, or `null` on error.

    - `error`: Contains a structured error object on failure, or `null` on success.

    - `metadata`: Contains the `request_id` and pagination information.


    ### WebSockets

    Real-time market data is available via WebSocket connections, which are not formally described in this OpenAPI specification. The following operations are available:

    - `market-data-l1-subscribe`: To start receiving L1 market data updates for a set of symbols.

    - `market-data-l1-unsubscribe`: To stop receiving L1 market data updates.'
  contact:
    name: Clear Street API Support
    url: https://clearstreet.io/contact
    email: concierge@clearstreet.com
  license:
    name: Proprietary
    url: https://clearstreet.io/terms
  version: 2025-10-31
servers:
- url: https://api.clearstreet.com
  description: Clear Street API
- url: https://api-dev.clearstreet.com
  description: Clear Street Development API
- url: http://localhost:5001
  description: Clear Street Local API
security:
- BearerAuth: []
tags:
- name: Omni AI
  description: Thread-centric AI assistant for conversational trading. Create threads to start conversations, poll response objects for in-progress output, and read finalized messages from thread history. Thread/message/response endpoints require an explicit account_id. Entitlement endpoints are caller-scoped and use account_ids.
paths:
  /v1/omni-ai/entitlement-agreements:
    get:
      tags:
      - Omni AI
      summary: Get Entitlement Agreements
      description: List current signable entitlement agreements for consent UX.
      operationId: get_entitlement_agreements
      responses:
        '200':
          description: Current signable entitlement agreements
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/EntitlementAgreementResourceList'
                type: object
        '404':
          description: No active signable agreements
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/entitlements:
    get:
      tags:
      - Omni AI
      summary: Get Entitlements
      description: List caller's active entitlement grants.
      operationId: get_entitlements
      parameters:
      - name: account_id
        in: query
        required: false
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: Caller's active entitlement grants
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/EntitlementResourceList'
                type: object
        '403':
          description: Caller lacks access to requested account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
    post:
      tags:
      - Omni AI
      summary: Create Entitlements
      description: Record consent and upsert one-or-more active grants.
      operationId: create_entitlements
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateEntitlementsRequest'
        required: true
      responses:
        '200':
          description: Resulting active grants for requested scope
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/EntitlementResourceList'
                type: object
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '403':
          description: Caller lacks access to one or more requested accounts
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/entitlements/{entitlement_id}:
    delete:
      tags:
      - Omni AI
      summary: Delete Entitlement
      description: Revoke one entitlement grant by id.
      operationId: delete_entitlement
      parameters:
      - name: entitlement_id
        in: path
        description: Entitlement grant id
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Grant revoked
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/DeleteEntitlementResponse'
                type: object
        '404':
          description: Grant not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '409':
          description: Grant already inactive
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/messages/{message_id}:
    get:
      tags:
      - Omni AI
      summary: Get Message By ID
      description: 'Get a finalized message by ID.


        Returns a single finalized message. Returns **404** if the message belongs

        to an in-progress assistant turn (use the response endpoint for live

        output). Once the turn completes, the message becomes available here.'
      operationId: get_message_by_id
      parameters:
      - name: message_id
        in: path
        description: Message identifier
        required: true
        schema:
          type: string
          format: uuid
      - name: account_id
        in: query
        description: Account ID for the request
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: Finalized message with content parts
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/Message'
                type: object
              examples:
                FinalizedAssistantMessage:
                  summary: Finalized assistant message with text and suggested actions
                  value:
                    data:
                      content:
                        parts:
                        - text: "**Pre-market as of 7:30 AM ET**\n\n ..."
                          type: text
                        - payload:
                            actionButtons:
                            - buttonId: btn_followup_0
                              label: Check my positions
                              prompt:
                                prompt: What are my current positions?
                          type: suggested_actions
                      created_at: 2026-04-16 09:20:17.309212+00:00
                      id: 019d9597-599c-7132-a7de-e5c21eaaab77
                      outcome: completed
                      role: ASSISTANT
                      seq: 2
                      thread_id: 019d9597-597c-7571-a0c9-a49c0e51f6eb
                    metadata:
                      request_id: 0f991501-757d-4051-bf00-6d7f452d6fcf
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingAccountId:
                  summary: Required account_id query parameter is missing
                  value:
                    error:
                      code: 400
                      message: 'Failed to deserialize query string: missing field `account_id`'
                    metadata:
                      request_id: e0c1c9f2-2100-40f0-b5fc-378a35dafa18
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                Forbidden:
                  summary: Caller does not have permission
                  value:
                    error:
                      code: 403
                      message: The caller does not have permission to execute the specified operation
                    metadata:
                      request_id: d68b5e7a-75f4-4a87-a349-3f7c57952578
        '404':
          description: Message not found or still in progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MessageNotFound:
                  summary: Requested message does not exist
                  value:
                    error:
                      code: 404
                      message: Message not found
                    metadata:
                      request_id: ec35dacd-36f1-4bf7-b138-00b15a3d09dd
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/messages/{message_id}/feedback:
    post:
      tags:
      - Omni AI
      summary: Submit Feedback
      description: 'Submit feedback on a finalized assistant message.


        Attaches a score and optional comment to a finalized assistant message.

        Feedback is only valid for messages with role `ASSISTANT` that have

        reached a terminal outcome.'
      operationId: submit_feedback
      parameters:
      - name: message_id
        in: path
        description: Finalized assistant message to rate
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateFeedbackRequest'
        required: true
      responses:
        '200':
          description: Feedback recorded
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/CreateFeedbackResponse'
                type: object
              examples:
                FeedbackRecorded:
                  summary: Feedback accepted and stored
                  value:
                    data:
                      created_at: 2026-04-23 16:09:51.746912+00:00
                      feedback_id: 019dbb1a-d782-7f42-8dd8-a1a7ca5d48e3
                    metadata:
                      request_id: 372a359a-fd4f-4c69-8f11-d80831aa5f23
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MalformedJsonSyntax:
                  summary: Malformed JSON payload
                  value:
                    error:
                      code: 400
                      message: 'Failed to parse the request body as JSON: trailing comma at line 3 column 1'
                    metadata:
                      request_id: 289d4f75-2220-4cbb-97cd-f0a64a87d470
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                Forbidden:
                  summary: Caller does not have permission
                  value:
                    error:
                      code: 403
                      message: The caller does not have permission to execute the specified operation
                    metadata:
                      request_id: 31d1fdeb-3fc6-4ded-b647-429ca7e79ffa
        '422':
          description: Malformed request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                PayloadMissingScore:
                  summary: Missing required score field in JSON body
                  value:
                    error:
                      code: 422
                      message: 'Failed to deserialize the JSON body into the target type: missing field `score` at line 3 column 1'
                    metadata:
                      request_id: cbe190c1-b260-4016-99c9-c507e923a2a5
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/responses/{response_id}:
    get:
      tags:
      - Omni AI
      summary: Get Response By ID
      description: 'Poll a response for assistant output.


        Returns the current snapshot of an in-progress or completed response.

        While the status is `queued` or `running`, the content may be partial and

        may include `thinking` parts. Poll this endpoint periodically until the

        status reaches a terminal value (`succeeded`, `failed`, or `canceled`).


        Once terminal, the finalized assistant message is available in thread

        history via `GET /omni-ai/threads/{thread_id}/messages`.'
      operationId: get_response_by_id
      parameters:
      - name: response_id
        in: path
        description: Response identifier (returned by create thread/message)
        required: true
        schema:
          type: string
          format: uuid
      - name: account_id
        in: query
        description: Account ID for the request
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: Current response snapshot with status and partial content
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/Response'
                type: object
              examples:
                ResponseSnapshot:
                  summary: Succeeded response with assistant output
                  value:
                    data:
                      content:
                        parts:
                        - text: '[AAPL](ticker:AAPL) is currently trading at ...'
                          type: text
                        - thoughts:
                          - Fetching current market data for AAPL...
                          type: thinking
                      id: 019dbafd-db54-7523-a412-ec9195cc5d99
                      output_message_id: 019dbafd-db61-73a0-8bd9-d4034d132f81
                      status: succeeded
                      thread_id: 019dbafd-db54-7523-a412-ec8a292246ad
                      user_message_id: 019dbafd-db56-78a2-8a91-d54a39f44174
                    metadata:
                      request_id: abc16101-2cbc-475a-84ef-98c8c588dcbb
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingAccountId:
                  summary: Required account_id query parameter is missing
                  value:
                    error:
                      code: 400
                      message: 'Failed to deserialize query string: missing field `account_id`'
                    metadata:
                      request_id: f5acc83c-57e7-4966-a699-17a9b552199b
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                Forbidden:
                  summary: Caller does not have permission
                  value:
                    error:
                      code: 403
                      message: The caller does not have permission to execute the specified operation
                    metadata:
                      request_id: b2d2d764-61f9-41c4-91c8-dd4366fc35c8
        '404':
          description: Response not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                ResponseNotFound:
                  summary: Requested response does not exist
                  value:
                    error:
                      code: 404
                      message: Response not found
                    metadata:
                      request_id: e232b453-b4a9-4594-a56f-85c1e62ef40f
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
    delete:
      tags:
      - Omni AI
      summary: Cancel Response
      description: 'Cancel a response.


        Requests cancellation of a queued or running response. If the response has

        already reached a terminal status, this is an idempotent success. A

        canceled turn still produces a final assistant message with outcome

        `canceled` in the thread history.'
      operationId: cancel_response
      parameters:
      - name: response_id
        in: path
        description: Response identifier to cancel
        required: true
        schema:
          type: string
          format: uuid
      - name: account_id
        in: query
        description: Account ID for the request
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: Cancellation accepted (idempotent)
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/CancelResponsePayload'
                type: object
              examples:
                CancellationResult:
                  summary: Response cancellation result
                  value:
                    data:
                      canceled: false
                    metadata:
                      request_id: fa26a786-f5d3-48b0-80eb-778e17af4964
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingAccountId:
                  summary: Required account_id query parameter is missing
                  value:
                    error:
                      code: 400
                      message: 'Failed to deserialize query string: missing field `account_id`'
                    metadata:
                      request_id: 10f877f8-130b-4f02-b40a-1b6ab5d8acdf
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                Forbidden:
                  summary: Caller does not have permission
                  value:
                    error:
                      code: 403
                      message: The caller does not have permission to execute the specified operation
                    metadata:
                      request_id: 1c610eec-b873-4092-93aa-f14b6f501e4b
        '404':
          description: Response not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                ResponseNotFound:
                  summary: Requested response does not exist
                  value:
                    error:
                      code: 404
                      message: Response not found
                    metadata:
                      request_id: a5bc6ea6-1b72-4f31-bb7d-2bd57151decc
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/threads:
    get:
      tags:
      - Omni AI
      summary: Get Threads
      description: 'List conversation threads.


        Returns thread metadata ordered by most recently created first. Use

        `page_size` and `page_token` for pagination. Thread objects contain only

        metadata (title, timestamps) — use the messages endpoint for conversation

        history.'
      operationId: get_threads
      parameters:
      - name: account_id
        in: query
        description: Account ID for the request
        required: true
        schema:
          type: integer
          format: int64
      - name: page_size
        in: query
        description: The number of items to return per page. Only used when page_token is not provided.
        required: false
        schema:
          type: integer
          format: int64
          default: 100
          maximum: 100
          minimum: 1
      - name: page_token
        in: query
        description: Token for retrieving the next or previous page of results. Contains encoded pagination state; when provided, page_size is ignored.
        required: false
        schema:
          type: string
          format: byte
          description: Base64URL-encoded pagination token
        example: eyJvZmZzZXQiOjEwMCwibGltaXQiOjEwMH0=
      responses:
        '200':
          description: Paginated list of thread metadata
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/ThreadList'
                type: object
              examples:
                ThreadsList:
                  summary: Single thread in list response
                  value:
                    data:
                    - created_at: 2026-04-23 15:15:54.929830+00:00
                      id: 019dbae9-73b3-7fe0-bd14-25fe57e91475
                      title: What is current price of AAPL?
                      updated_at: 2026-04-23 15:15:54.929830+00:00
                    metadata:
                      request_id: eb95e1b8-d245-41b1-bbd0-cc1073e68bfd
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingAccountId:
                  summary: Required account_id query parameter is missing
                  value:
                    error:
                      code: 400
                      message: 'Failed to deserialize query string: missing field `account_id`'
                    metadata:
                      request_id: 3d8aa540-5f00-4efe-bf63-e55ee65ac14b
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
    post:
      tags:
      - Omni AI
      summary: Create Thread
      description: "Create a new conversation thread.\n\nAtomically creates a new thread and submits the first user turn. The\nresponse contains a `response_id` that should be polled via\n`GET /omni-ai/responses/{response_id}` for assistant output.\n\nTwo creation modes are supported:\n- **instant** — provide `text` with a natural-language prompt.\n- **deep_insights** — provide a `target` ticker and optional `thesis`\n  for long-form research."
      operationId: create_thread
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateThreadRequest'
        required: true
      responses:
        '200':
          description: Thread created. Poll the returned `response_id` for assistant output.
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/CreateThreadResponse'
                type: object
              examples:
                ThreadCreated:
                  summary: Thread created successfully
                  value:
                    data:
                      response_id: 019dbae9-73b4-7760-a947-8b4bcab57c49
                      thread_id: 019dbae9-73b3-7fe0-bd14-25fe57e91475
                      user_message_id: 019dbae9-73b8-75b2-9c06-ac348927696d
                    metadata:
                      request_id: f7a9ad4d-753a-403e-aa0e-ca151f991a81
        '400':
          description: Invalid request (missing required fields or invalid mode)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingInstantText:
                  summary: text is required in instant mode
                  value:
                    error:
                      code: 400
                      message: text is required for instant mode
                    metadata:
                      request_id: c075d493-8499-40e3-8ce1-411e205f0380
        '422':
          description: Malformed request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                PayloadMissingType:
                  summary: Missing required `type` field in JSON body
                  value:
                    error:
                      code: 422
                      message: 'Failed to deserialize the JSON body into the target type: missing field `type` at line 3 column 1'
                    metadata:
                      request_id: 625523fe-02ba-4a74-8544-81f43f204b59
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/omni-ai/threads/{thread_id}:
    get:
      tags:
      - Omni AI
      summary: Get Thread By ID
      description: 'Get a specific thread.


        Returns metadata (title, timestamps) for a single thread. Does not include

        messages — use `GET /omni-ai/threads/{thread_id}/messages` for conversation

        history.'
      operationId: get_thread_by_id
      parameters:
      - name: thread_id
        in: path
        description: Thread identifier
        required: true
        schema:
          type: string
          format: uuid
      - name: account_id
        in: query
        description: Account ID for the request
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          description: Thread metadata
          content:
            application/json:
              schema:
                allOf:
                - $ref: '#/components/schemas/BaseResponse'
                - type: object
                  required:
                  - data
                  properties:
                    data:
                      $ref: '#/components/schemas/Thread'
                type: object
              examples:
                ThreadMetadata:
                  summary: Thread metadata for a single thread
                  value:
                    data:
                      created_at: 2026-04-23 15:15:54.929830+00:00
                      id: 019dbae9-73b3-7fe0-bd14-25fe57e91475
                      title: What is current price of AAPL?
                      updated_at: 2026-04-23 15:15:54.929830+00:00
                    metadata:
                      request_id: 5683a394-6dd1-4843-8591-f102ced2e636
        '400':
          description: Invalid query parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                MissingAccountId:
                  summary: Required account_id query parameter is missing
                  value:
                    error:
                      code: 400
                      message: 'Failed to deserialize query string: missing field `account_id`'
                    metadata:
                      request_id: e949291a-3817-4e72-8298-90420c86e6be
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                Forbidden:
                  summary: Caller does not have permission
                  value:
                    error:
                      code: 403
                      message: The caller does not have permission to execute the specified operation
                    metadata:
                      request_id: 31d1fdeb-3fc6-4ded-b647-429ca7e79ffa
        '404':
          description: Thread not found or not owned by this user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              examples:
                ThreadNotFound:
                  summary: Thread does not exist for this account/user
                  value:
                    error:
                      code: 404
                      message: Thread not found
                    metadata:
                      request_id: f1556e8f-a7aa-43d3-b7d1-2229e266ada7
        '500':


# --- truncated at 32 KB (82 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/clear-street/refs/heads/main/openapi/clear-street-omni-ai-api-openapi.yml