> ## Documentation Index
> Fetch the complete documentation index at: https://docs.linqalpha.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics V2

> Agentic analytics with structured source selection, hard/soft filters, and identity fields.

- **`search_types`**: Choose sources — `rms` (internal docs), `external` (transcripts, filings), `structured`
- **`filters.rms.hard_filters` / `soft_filters`**: Hard = exclude non-matching (AND between fields, OR within arrays). Soft = boost relevance only.
- `organization_id` and `user_id`: Optional (required only for platform API keys)

## Event Flow

```
conversation            ← conversation_id
message                 ← echo of user query
status: start           ← stream begins
+-- AGENTIC LOOP (repeats) ---------+
|  tool_use_block (x1-3)            |
|  tool_result_block (x1-3)         |
|  keepalive (~15s)                 |
|  think (xN)                       |
+------------------------------------+
answer                  ← full answer with [1][2] citations
status: finish          ← stream ends
```

## Retrieving References

After the stream finishes, use `conversation_id` to get citation sources:

```
GET /v2/analytics/conversations/{conversation_id}/references
```

Returns normalized references with enriched metadata. See [Analytics V2 References](/api-reference/basic/analytics_references) for details.

## Referencing Vault documents

To chat over documents you uploaded through the Vault endpoints, pass their `rms_document_id` (returned by [Vault — Confirm Upload](/api-reference/vault/confirm)) in `search_types.rms[].document_ids`, and **set `source` to `"vault"`**:

```json theme={null}
{
  "organization_id": "<org uuid>",
  "query": "Summarize the Q3 figures in the uploaded report.",
  "search_types": {
    "rms": [
      { "workspace": "personal", "source": "vault", "document_ids": ["<rms_document_id>"] }
    ]
  }
}
```

<Warning>
  `source: "vault"` is **required** for Vault documents. If you omit it, the document is searched generically — it is not retrieved for direct file citation, the answer's `[N]` markers won't resolve, and `GET /v2/analytics/conversations/{id}/references` returns an empty list (the answer may still look complete, so this fails silently).
</Warning>

* `document_ids` are **`rms_document_id`** values from `confirm` (poll [Document Status](/api-reference/vault/status) until `Synced` first) — not the presign `document_id`.
* `workspace` must match the workspace the document was uploaded into (the `workspace` sent to `presigned_url` / `confirm`).


## OpenAPI

````yaml POST /v2/analytics/sse
openapi: 3.0.1
info:
  title: LinqAlpha API
  description: >-
    Linq helps finance professionals make informed decisions using
    Retrieval-Augmented Generation (RAG)-enhanced answers. By leveraging
    cutting-edge Large Language Models (LLM) and supplementary technology, Linq
    provides the most optimized responses based on your queries.
  version: 1.0.0
  license:
    name: MIT
servers:
  - url: https://api.linqalpha.com
security:
  - ApiKeyAuth: []
tags:
  - name: Search
    description: Search and generate responses
  - name: Data
    description: Data retrieval and mapping
  - name: Feedback
    description: Conversation feedback
  - name: RMS
    description: Research Management System
  - name: Source Management
    description: Source batch and file management
  - name: MCP
    description: >-
      LinqAlpha MCP — Financial data tools for AI assistants via Model Context
      Protocol
  - name: Connectors
    description: Customer Connectors — customer-owned MCP connector management
  - name: Briefing
    description: Briefing Agent — automated market briefings with scheduling and delivery
  - name: Status
    description: Sync status — check organization, document, and container sync progress
paths:
  /v2/analytics/sse:
    post:
      tags:
        - Search
      summary: Generate an analytics response via SSE (V2)
      description: >-
        Agentic analytics with structured source selection, hard/soft filters,
        and identity fields.


        - **`search_types`**: Choose sources — `rms` (internal docs), `external`
        (transcripts, filings), `structured`

        - **`filters.rms.hard_filters` / `soft_filters`**: Hard = exclude
        non-matching (AND between fields, OR within arrays). Soft = boost
        relevance only.

        - `organization_id` and `user_id`: Optional (required only for platform
        API keys)


        ## Event Flow


        ```

        conversation            ← conversation_id

        message                 ← echo of user query

        status: start           ← stream begins

        +-- AGENTIC LOOP (repeats) ---------+

        |  tool_use_block (x1-3)            |

        |  tool_result_block (x1-3)         |

        |  keepalive (~15s)                 |

        |  think (xN)                       |

        +------------------------------------+

        answer                  ← full answer with [1][2] citations

        status: finish          ← stream ends

        ```


        ## Retrieving References


        After the stream finishes, use `conversation_id` to get citation
        sources:


        ```

        GET /v2/analytics/conversations/{conversation_id}/references

        ```


        Returns normalized references with enriched metadata. See [Analytics V2
        References](/api-reference/basic/analytics_references) for details.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyticsV2Request'
            examples:
              basic:
                summary: Basic query with external sources only
                value:
                  query: What are the latest insights on AAPL performance?
                  search_types:
                    external:
                      - type: transcript
                      - type: filing
              multi_turn:
                summary: Multi-turn continuation with existing conversation
                value:
                  query: Can you also compare with MSFT?
                  conversation_id: 12345678-93ee-44bb-afb3-d60df76e31bf
                  search_types:
                    external:
                      - type: transcript
                      - type: filing
                  filters:
                    rms:
                      hard_filters:
                        tickers:
                          - AAPL US
                          - MSFT US
      responses:
        '200':
          description: >-
            SSE stream of analytics events. Each event is sent as `data:
            {json}\n\n`. Events follow the sequence: conversation → message →
            status:start → [agentic loop] → answer → status:finish.
            status:keep_alive and keepalive events are sent periodically during
            long tool execution gaps.
          content:
            text/event-stream:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ConversationEvent'
                  - $ref: '#/components/schemas/AnalyticsMessageEvent'
                  - $ref: '#/components/schemas/AnalyticsStatusEvent'
                  - $ref: '#/components/schemas/AnalyticsThinkEvent'
                  - $ref: '#/components/schemas/AnalyticsToolUseBlockEvent'
                  - $ref: '#/components/schemas/AnalyticsToolResultBlockEvent'
                  - $ref: '#/components/schemas/AnalyticsAnswerEvent'
                  - $ref: '#/components/schemas/AnalyticsKeepaliveEvent'
                  - 5feb9295-53ff-4168-9134-ff9dfaf2f511
              examples:
                conversation:
                  summary: Conversation Event
                  description: First event — returns the conversation identifier
                  value:
                    event_name: conversation
                    data:
                      conversation_id: 7622b901-93ee-44bb-afb3-d60df76e31bf
                      message: Successfully created a conversation.
                message:
                  summary: Message Event
                  description: Second event - echoes the user's query
                  value:
                    event_name: message
                    data:
                      message_id: 98
                      message_type: user
                      message: >-
                        What are the latest NVIDIA earnings results? Compare
                        revenue growth vs AMD.
                status_start:
                  summary: Status Start Event
                  description: Stream has started processing
                  value:
                    event_name: status
                    data:
                      status: start
                think:
                  summary: Think Event
                  description: Streamed reasoning process (sent incrementally)
                  value:
                    event_name: think
                    data:
                      think_piece: >-
                        I need to look up NVIDIA's latest earnings data and
                        compare it with AMD...
                tool_use_block:
                  summary: Tool Use Block Event
                  description: >-
                    Tool invocation during analysis. Multiple may be sent in
                    parallel.
                  value:
                    event_name: tool_use_block
                    data:
                      name: mcp__linq__factset_query
                      input:
                        sql: >-
                          SELECT fe.TICKER, fp.FY_END_DATE, fp.FF_SALES FROM
                          FF_V3.FF_BASIC_AF fp JOIN FE_V4.FE_BASIC_TICKER fe ON
                          fe.FSYM_ID = fp.FSYM_ID WHERE fe.TICKER IN ('NVDA',
                          'AMD')
                tool_result_block:
                  summary: Tool Result Block Event
                  description: Result from a tool execution
                  value:
                    event_name: tool_result_block
                    data:
                      content: '{"success": true, "total_matches": 24, "results": [...]}'
                answer:
                  summary: Answer Event
                  description: >-
                    Complete final answer (sent as a single event, not streamed
                    incrementally)
                  value:
                    event_name: answer
                    data:
                      answer_piece: |-
                        ## NVIDIA vs AMD: Earnings Comparison

                        NVIDIA reported record revenue of $35.1B...
                keepalive:
                  summary: Keepalive Event
                  description: Heartbeat sent during idle periods (>15s gap between events)
                  value:
                    event_name: keepalive
                    data:
                      timestamp: '2026-02-26T22:46:50.780316'
                status_finish:
                  summary: Status Finish Event
                  description: Stream has completed
                  value:
                    event_name: status
                    data:
                      status: finish
                status_keep_alive:
                  summary: Status Keep Alive Event
                  description: >-
                    Sent periodically during long tool execution gaps (in
                    addition to keepalive events)
                  value:
                    event_name: status
                    data:
                      status: keep_alive
        '400':
          description: Bad Request - Invalid request parameters or incorrect format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST_BODY
                  msg: query is required and must be a string
                  message: query is required and must be a string
                payload: null
        '401':
          description: Unauthorized - Invalid API key or authentication credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: API_KEY_MISSING
                  msg: header does not contain api key
                  message: header does not contain api key
                payload: null
components:
  schemas:
    AnalyticsV2Request:
      type: object
      properties:
        organization_id:
          type: string
          format: uuid
          description: Organization ID
        user_id:
          type: string
          format: uuid
          description: User ID
        user_email:
          type: string
          format: email
          description: User email
        user_name:
          type: string
          description: User name
        query:
          type: string
          description: The analytics query to process.
          example: What are the latest insights on AAPL earnings?
        conversation_id:
          type: string
          nullable: true
          description: >-
            Existing conversation ID for multi-turn continuation. Omit or null
            for new conversation.
        search_types:
          type: object
          nullable: true
          description: >-
            Structured source selection. Controls which document sources to
            query. Omitting a category means don't search it.
          properties:
            rms:
              type: array
              nullable: true
              items:
                type: object
                properties:
                  workspace:
                    type: string
                    enum:
                      - personal
                      - organization
                    description: Workspace scope
                  source:
                    type: string
                    nullable: true
                    description: >-
                      Source type for this RMS selection. For Vault-uploaded
                      documents (referenced by their rms_document_id in
                      document_ids), you MUST set source to "vault". If omitted,
                      the documents are searched generically: they are not
                      retrieved for direct file citation, the answer's [N]
                      markers won't resolve, and GET
                      /v2/analytics/conversations/{id}/references returns an
                      empty list.
                  type:
                    type: string
                    nullable: true
                  subtypes:
                    type: array
                    items:
                      type: string
                    nullable: true
                  container_ids:
                    type: array
                    items:
                      type: string
                    nullable: true
                  document_ids:
                    type: array
                    items:
                      type: string
                    nullable: true
                required:
                  - workspace
            external:
              type: array
              nullable: true
              description: Third-party sources
              items:
                type: object
                properties:
                  type:
                    type: string
                  subtypes:
                    type: array
                    items:
                      type: string
                    nullable: true
                  document_ids:
                    type: array
                    items:
                      type: string
                    nullable: true
                required:
                  - type
            structured:
              type: array
              nullable: true
              items:
                type: object
                properties:
                  type:
                    type: string
                required:
                  - type
        filters:
          type: object
          nullable: true
          description: >-
            Metadata filters. Hard filters exclude non-matching documents (AND
            between fields, OR within arrays). Soft filters boost relevance
            without excluding.
          properties:
            rms:
              type: object
              nullable: true
              properties:
                hard_filters:
                  type: object
                  nullable: true
                  description: >-
                    Strict metadata constraints for internal sources. AND
                    between fields, OR within arrays.
                soft_filters:
                  type: object
                  nullable: true
                  description: >-
                    Preferred but not required metadata for internal sources.
                    Boosts relevance.
            external:
              type: object
              nullable: true
              properties:
                soft_filters:
                  type: object
                  nullable: true
                  description: >-
                    Preferred metadata for external sources. No hard filters on
                    external by design.
        connectors:
          type: array
          nullable: true
          description: Customer MCP connectors to enable for this analytics request.
          items:
            type: object
            additionalProperties: true
            properties:
              name:
                type: string
                description: Connector name
              tool_filter:
                type: array
                nullable: true
                items:
                  type: string
                description: Optional tool allow-list for this connector
            required:
              - name
        disabled_connectors:
          type: array
          nullable: true
          description: Connector names to disable for this analytics request.
          items:
            type: string
      required:
        - query
    ConversationEvent:
      description: Conversation event
      allOf:
        - $ref: '#/components/schemas/ChatSseEvent'
        - properties:
            event_name:
              enum:
                - conversation
            data:
              type: object
              required:
                - conversation_id
              properties:
                conversation_id:
                  type: string
                  description: >-
                    Unique conversation identifier. Use for multi-turn
                    continuation and References API.
                message:
                  type: string
                  description: >-
                    Status message (e.g., 'Successfully created a
                    conversation.')
              description: Event-specific data payload
    AnalyticsMessageEvent:
      description: >-
        User message echo event. Second event in the stream (after
        conversation), echoing the user's query.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - message
            data:
              type: object
              required:
                - message_id
                - message_type
                - message
              properties:
                message_id:
                  type: integer
                  description: Unique message identifier
                message_type:
                  type: string
                  enum:
                    - user
                    - assistant
                  description: Type of message
                message:
                  type: string
                  description: The message content
    AnalyticsStatusEvent:
      description: >-
        Stream status event indicating start, finish, or keep_alive of the
        analytics stream.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - status
            data:
              type: object
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - start
                    - finish
                    - keep_alive
                  description: >-
                    Stream lifecycle status. 'keep_alive' is sent periodically
                    during long tool execution gaps.
    AnalyticsThinkEvent:
      description: >-
        Thinking/reasoning process stream. Sent as the model reasons through the
        problem.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - think
            data:
              type: object
              required:
                - think_piece
              properties:
                think_piece:
                  type: string
                  description: >-
                    A piece of the thinking/reasoning process (streamed
                    incrementally)
    AnalyticsToolUseBlockEvent:
      description: >-
        Tool invocation event. Indicates a tool is being called during analysis.
        Multiple tool_use_block events may be sent in parallel batches.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - tool_use_block
            data:
              type: object
              required:
                - name
                - input
              properties:
                name:
                  type: string
                  description: >-
                    Name of the tool being called (e.g.,
                    mcp__linq__manticore_sql, mcp__linq__factset_query)
                  example: mcp__linq__manticore_sql
                input:
                  type: object
                  description: >-
                    Input arguments passed to the tool. Structure varies by
                    tool.
                  additionalProperties: true
    AnalyticsToolResultBlockEvent:
      description: Tool execution result event. Contains the output from a tool call.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - tool_result_block
            data:
              type: object
              required:
                - content
              properties:
                content:
                  type: string
                  description: JSON-encoded result from the tool execution
    AnalyticsAnswerEvent:
      description: >-
        Final answer event. Contains the complete answer in a single event (not
        streamed incrementally).
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - answer
            data:
              type: object
              required:
                - answer_piece
              properties:
                answer_piece:
                  type: string
                  description: >-
                    The complete final answer content. Unlike other SSE
                    endpoints, analytics sends the full answer in a single event
                    rather than streaming it incrementally.
    AnalyticsKeepaliveEvent:
      description: >-
        Heartbeat event sent periodically (every ~15s during idle periods) to
        keep the connection alive.
      allOf:
        - $ref: '#/components/schemas/AnalyticsSseEvent'
        - properties:
            event_name:
              enum:
                - keepalive
            data:
              type: object
              required:
                - timestamp
              properties:
                timestamp:
                  type: string
                  format: date-time
                  description: ISO 8601 timestamp of the keepalive event
                  example: '2026-02-26T22:46:50.780316'
    ApiErrorResponse:
      type: object
      description: Standard error response wrapper
      properties:
        error:
          $ref: '#/components/schemas/ApiError'
        payload:
          description: Always null for error responses
          nullable: true
      required:
        - error
        - payload
    ChatSseEvent:
      type: object
      description: Base structure for all Chat SSE events
      required:
        - event_name
        - data
      properties:
        event_name:
          type: string
          enum:
            - conversation
            - status
            - think
            - sub_questions
            - dialogue_id
            - search_results
            - answer
        data:
          type: object
          description: Event-specific data payload
    AnalyticsSseEvent:
      type: object
      description: Base structure for all Analytics SSE events
      required:
        - event_name
        - data
      properties:
        event_name:
          type: string
          enum:
            - message
            - status
            - think
            - tool_use_block
            - tool_result_block
            - answer
            - keepalive
          description: Type of event in the analytics stream
        data:
          type: object
          description: Event-specific data payload
    ApiError:
      type: object
      properties:
        code:
          type: string
          description: >-
            Error code indicating the type of error. Common codes:

            - Authentication: `API_KEY_MISSING`, `INVALID_API_KEY`

            - Validation: `INVALID_REQUEST_BODY`, `ORGANIZATION_ID_MISSING`,
            `TICKERS_MISSING`, `CHAT_MESSAGE_ID_MISSING`, `DOCUMENT_ID_MISSING`

            - Service: `SEARCH_FAIL`, `TTS_FAIL`, `CREATE_CONV_FAIL`,
            `GET_STOCK_FAIL`, `CREATE_MSG_FAIL`, `ALPHA_COMP_FAIL`,
            `GET_REF_FAIL`

            - Connectors: `CONNECTOR_LIST_FAIL`, `CONNECTOR_NOT_FOUND`,
            `CONNECTOR_CREATE_FAIL`, `CONNECTOR_UPDATE_FAIL`,
            `CONNECTOR_DELETE_FAIL`, `CONNECTOR_TEST_FAIL`

            - Not Found: `NOT_FOUND`
          example: INVALID_REQUEST_BODY
        msg:
          type: string
          description: Error message (deprecated, use `message` instead)
          example: query is required and must be a string
        message:
          type: string
          description: Error message providing more details about the error
          example: query is required and must be a string
      required:
        - code
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY

````