LinqAlpha Search API

Search and generate responses

OpenAPI Specification

linqalpha-search-api-openapi.yml Raw ↑
openapi: 3.0.1
info:
  title: LinqAlpha Briefing Search 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
paths:
  /v2/analytics/messages/{chat_message_id}/judge:
    post:
      summary: Analytics V2 Judge (source-grounding)
      tags:
      - Search
      description: 'Runs a source-grounding judge over one Analytics answer. You supply the answer''s `chat_message_id` plus your own judging `prompt` (and an optional `response_schema`); we resolve the original prompt, the generated answer, and every reference the answer cited, run a tool-less GPT-4.1 over them, and return a verdict shaped by your schema.


        **Usage flow:**

        1. Call `POST /v2/analytics/sse`; while consuming the stream, capture the `chat_message_id` event.

        2. POST that id here with your `prompt` — your prompt is the entire judging instruction; we add no criteria of our own — and an optional `response_schema`.

        3. The verdict scores how well each claim is grounded in the sources the answer actually cited (a number that contradicts its source, or is absent from all sources, is flagged as not grounded).


        Tenant-scoped: you can only judge answers generated by your own organization; others return 404.'
      parameters:
      - name: chat_message_id
        in: path
        description: The assistant answer's ChatMessage UUID. Emitted as the `chat_message_id` event on the Analytics SSE V2 stream.
        required: true
        schema:
          type: string
          format: uuid
        example: 5b37f46c-f5de-4b8a-af09-5058dd4779b3
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - prompt
              properties:
                prompt:
                  type: string
                  maxLength: 50000
                  description: Your judging instruction, used verbatim as the judge's system prompt.
                response_schema:
                  type: object
                  additionalProperties: true
                  description: Optional JSON Schema for the verdict shape (must serialize to at most 100000 bytes). Omit to use the default verdict schema.
            example:
              prompt: 'For each section of the answer, return: (1) a score from 0 to 10 reflecting how well its claims are grounded in the cited sources [N], (2) a concise summary, and (3) a short report covering Strengths, Weaknesses, and any Contradicted or unverifiable facts. Any figure or rating absent from the cited sources must appear under Contradicted or unverifiable.'
              response_schema:
                type: object
                properties:
                  section_scores:
                    type: object
                    additionalProperties:
                      type: number
                  section_content_summaries:
                    type: object
                    additionalProperties:
                      type: string
                  report:
                    type: string
                required:
                - section_scores
                - section_content_summaries
                - report
      responses:
        '200':
          description: Grounding verdict, shaped by your `response_schema`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    nullable: true
                  payload:
                    type: object
                    properties:
                      chat_message_id:
                        type: string
                        format: uuid
                      verdict:
                        type: object
                        additionalProperties: true
                      judge_model:
                        type: string
                      references_evaluated:
                        type: integer
              example:
                error: null
                payload:
                  chat_message_id: 5b37f46c-f5de-4b8a-af09-5058dd4779b3
                  verdict:
                    section_scores:
                      Market Snapshot: 9.5
                      What CLSA Says: 8.0
                    section_content_summaries:
                      Market Snapshot: Index levels and deltas match the cited FactSet/market-data sources.
                      What CLSA Says: Ratings and targets trace to the cited CLSA notes; one target could not be verified against any cited source.
                    report: '## Market Snapshot

                      - Strengths: index levels match the cited sources.

                      - Contradicted or unverifiable: none.


                      ## What CLSA Says

                      - Weaknesses: one price target is absent from the cited notes (flagged).'
                  judge_model: gpt-4.1
                  references_evaluated: 24
        '400':
          description: Bad Request — invalid `chat_message_id` or body (e.g. missing `prompt`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: INVALID_REQUEST_BODY
                  msg: prompt is required
                  message: prompt is required
                payload: null
        '401':
          description: Unauthorized — missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '404':
          description: Not found — the answer does not exist or was not generated by your organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '422':
          description: Unprocessable Entity — invalid `response_schema`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '502':
          description: Bad Gateway — upstream judge failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '504':
          description: Gateway Timeout — the judge is a long-running LLM call.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
  /v1/search:
    post:
      summary: Search
      description: 'LinqAlpha uses multiple data sources and retrieval methods to find the most relevant documents or information based on a query. Unlike the generate endpoint, this API only performs the search step and returns matched results without generating a response.


        **How to view original documents:**

        1. **Via Viewer:** `https://chat.linqalpha.com/rms/viewer?chat_message_id={chat_message_id}&citation_idx={citation_idx}`

        2. **Direct Download:** If the reference contains a `document_id`, you can access the original document directly through the [presigned_url endpoint](https://docs.linqalpha.com/api-reference/basic/presigned_url).'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
            example:
              query: What are the latest news on AAPL?
              stock_ids:
              - BBG001S5N8V8
              tickers:
              - AAPL
              external_types:
              - transcript
              - filing
              - news
              - ir_slide
      responses:
        '200':
          description: Search response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
              example:
                chat_message_id: 123e4567-e89b-12d3-a456-426614174000
                search_result_count: 38
                execution_time_ms: 10355
                references:
                - id: '12'
                  citation_idx: '12'
                  search_type: rms
                  chunk_id: 123e4567-e89b-12d3-a456-426614174000
                  text: For fiscal year 2024, Tesla expects EBIT to grow between 15% and 20%...
                  text_type: paragraph
                  document_name: Tesla 10-K 2023
                  external_url: https://www.sec.gov/ix?doc=/Archives/edgar/data/1318605/000095017024002308/tsla-20231231.htm
                  metadata:
                    source: filing
                    ticker: TSLA
                    published_at: '2024-02-14'
                  custom_metadata: null
        '400':
          description: Bad Request - Invalid request parameters or incorrect format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              examples:
                invalid_upload_period:
                  summary: Invalid upload_period format
                  value:
                    error:
                      code: INVALID_REQUEST_BODY
                      message: 'upload_period.start_time must be an object with year (integer), month (integer 1-12), and optional day (integer 1-31). Example: {"year": 2025, "month": 1, "day": 1}'
                    payload: null
                missing_query:
                  summary: Missing required field
                  value:
                    error:
                      code: INVALID_REQUEST_BODY
                      message: query is required and must be a string
                    payload: null
        '401':
          description: Unauthorized - Invalid 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
        '403':
          description: Forbidden - No permission to access this resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: FORBIDDEN
                  message: 'Access denied: insufficient permissions.'
                payload: null
        '404':
          description: Not Found - The requested resource does not exist.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: NOT_FOUND
                  message: The requested resource was not found.
                payload: null
        '500':
          description: Internal Server Error - An unexpected error occurred on the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: SERVER_ERROR
                  message: An unexpected error occurred on the server.
                payload: null
      tags:
      - Search
  /v2/chat/sse:
    post:
      summary: Generate a response from the LinqAlpha engine via SSE
      description: 'Generate a response from the LinqAlpha engine. LinqAlpha uses different types of language models and data sources to generate an answer. The response is provided as a server-sent events (SSE) stream.


        **Note**: For this search chat endpoint, the stock_id (BBG_ID) can be obtained by referring to the [Map Tickers API](https://docs.linqalpha.com/api-reference/basic/map_tickers) and using the `stock_id` value from its response.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatSseV2Request'
            example:
              query: What are the latest insights on AAPL performance?
              stock_ids:
              - BBG001S5N8V8
              tickers:
              - AAPL
              external_types:
              - transcript
              - filing
              - news
              - ir_slide
      responses:
        '200':
          description: SSE stream response with RMS search results
          content:
            text/event-stream:
              schema:
                oneOf:
                - $ref: '#/components/schemas/ConversationEvent'
                - $ref: '#/components/schemas/ThinkEvent'
                - $ref: '#/components/schemas/SubQuestionsEvent'
                - $ref: '#/components/schemas/StatusEvent'
                - $ref: '#/components/schemas/DialogueIdEvent'
                - $ref: '#/components/schemas/SearchResultsEvent'
                - $ref: '#/components/schemas/AnswerEvent'
                discriminator:
                  propertyName: event_name
                  mapping:
                    conversation: '#/components/schemas/ConversationEvent'
                    think: '#/components/schemas/ThinkEvent'
                    sub_questions: '#/components/schemas/SubQuestionsEvent'
                    status: '#/components/schemas/StatusEvent'
                    dialogue_id: '#/components/schemas/DialogueIdEvent'
                    search_results: '#/components/schemas/SearchResultsEvent'
                    answer: '#/components/schemas/AnswerEvent'
              examples:
                conversation_created:
                  summary: 2. Conversation Created Event
                  description: Conversation creation event - first event in the stream
                  value:
                    event_name: conversation
                    data:
                      conversation_id: 123e4567-e89b-12d3-a456-426614174000
                think_event:
                  summary: 3. Think Event
                  description: Streamed reasoning/planning process
                  value:
                    event_name: think
                    data:
                      think_piece: <PLAN_REASONING>
                sub_questions_event:
                  summary: 4. Sub Questions Event
                  description: Sub-questions generated for the current message
                  value:
                    event_name: sub_questions
                    data:
                      sub_questions:
                      - What is the latest news about JP morgan equity research asia?
                      - What is the latest news about JP morgan equity research asia?
                status_event:
                  summary: 5. Status Event - Finish
                  description: Indicates stream has completed
                  value:
                    event_name: status
                    data:
                      status: finish
                dialogue_id_event:
                  summary: 6. Dialogue ID Event
                  description: Unique identifier for the current dialogue
                  value:
                    event_name: dialogue_id
                    data:
                      dialogue_id: 123e4567-e89b-12d3-a456-426614174000
                search_results_event:
                  summary: 7. Search Results ID Event
                  description: Unique identifier for the search results
                  value:
                    event_name: search_results
                    data:
                      chat_message_id: 123e4567-e89b-12d3-a456-426614174000
                answer_event:
                  summary: 8. Answer Event
                  description: Streamed answer content
                  value:
                    event_name: answer
                    data:
                      answer_piece: Based on the latest research...
        '400':
          description: Bad Request - Invalid request parameters or incorrect format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              examples:
                invalid_upload_period:
                  summary: Invalid upload_period format
                  value:
                    error:
                      code: INVALID_REQUEST_BODY
                      message: 'upload_period.start_time must be an object with year (integer), month (integer 1-12), and optional day (integer 1-31). Example: {"year": 2025, "month": 1, "day": 1}'
                    payload: null
                missing_query:
                  summary: Missing required field
                  value:
                    error:
                      code: INVALID_REQUEST_BODY
                      message: query is required and must be a string
                    payload: null
        '401':
          description: Unauthorized - Invalid 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
        '500':
          description: Internal Server Error - An unexpected error occurred on the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                error:
                  code: SERVER_ERROR
                  message: An unexpected error occurred on the server.
                payload: null
      tags:
      - Search
  /v1/analytics/sse:
    post:
      summary: Generate an analytics response via SSE
      description: 'Generate an agentic analytics response via Server-Sent Events. This endpoint leverages multi-step reasoning with tool use to deliver deeper, more comprehensive answers compared to the standard search & generate endpoints.


        The response stream includes message echo, thinking processes, tool calls with results, and the final answer.


        **Note:** Unlike `/v1/search` or `/v2/chat/sse`, this endpoint does not accept separate filter parameters (e.g., `stock_ids`, `tickers`, `external_types`, `upload_period`). Instead, include all filtering context directly in the `query` field. For example: `"Analyze AAPL earnings trend from Q1 2024 to Q4 2025"`.


        ### Event Flow


        ```

        conversation          -> conversation_id for this session

        message               -> echo of user query

        status: start         -> stream begins

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

        |  tool_use_block     -> 1-N parallel tool calls (batch)|

        |  tool_result_block  -> results for each call          |

        |  status: keep_alive -> heartbeat (if >15s gap)        |

        |  think (x N)        -> reasoning tokens               |

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

        think (x N)           -> extended reasoning / draft

        answer                -> single chunk final answer

        status: finish        -> stream ends

        ```'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnalyticsRequest'
            example:
              query: Analyze AAPL earnings trend over the past 4 quarters
      responses:
        '200':
          description: 'SSE stream of analytics events. Each event is sent as `data: {json}\n\n`. The stream contains multiple event types in sequence. See the Event Flow section above for the typical ordering.'
          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'
              examples:
                conversation:
                  summary: Conversation Event
                  description: First event - returns the conversation identifier for this session
                  value:
                    event_name: conversation
                    data:
                      conversation_id: 123e4567-e89b-12d3-a456-426614174000
                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
        '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
      tags:
      - Search
  /v2/analytics/sse:
    post:
      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'
                - $ref: '#/components/schemas/AnalyticsCostMetadataEvent'
              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

# --- truncated at 32 KB (66 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/linqalpha/refs/heads/main/openapi/linqalpha-search-api-openapi.yml