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

# Matched markets with identifiers, outcomes, and current reference prices

> Returns the same verified, live-filtered pair catalog as `/matched-markets`, with `details` and `pricing` attached to both sides. Unsupported markets, missing quotes, and individual venue failures produce `pricing: null` without changing pair membership or pagination. Prices use each venue's API scale and are reference prices, not executable bids or asks. The page is capped at 150 pairs to bound request cost. Responses are not cacheable.



## OpenAPI

````yaml /openapi/data-api.yaml get /matched-markets/enriched
openapi: 3.1.0
info:
  title: Kairos Data API
  version: 1.0.0
  summary: >-
    The full Kairos data plane — markets, candles, trades, search, discover,
    sports, trader analytics, and PnL.
  description: |
    The Kairos Data API at `data.kairos.trade` is the platform's primary data
    plane: market metadata and prices, OHLCV candles, live venue trade proxies,
    normalized trade history, full-text search, discovery feeds, the sports
    catalog, public trader analytics, and account PnL.

    ## Authentication

    Most endpoints accept a Kairos **API key** (`X-Client-Id` + `X-Api-Key` +
    `X-Api-Secret`, all three) or a first-party session JWT. Endpoints tagged
    `public` (trader analytics, provider configs, several sports feeds) need
    no credentials at all. Some endpoints additionally require an API-key
    **scope** (`trade:read`, `position:read`) — stated per operation.

    For high-volume market-data consumption (candles/trades/metadata at
    scale), prefer the dedicated **Market Data API** at `md.kairos.trade` —
    it has higher budgets, ETag caching, and a binary candle format.

    ## Rate limits

    Rate limits use a sliding window keyed on the authenticated user (JWT
    `sub`) or, for anonymous callers, the trusted client IP. Routes belong to
    a named **bucket** (`x-kairos-bucket`) whose per-minute budget is shared
    by every route in it; routes with no bucket run under the service default
    of 100/minute. `x-kairos-rate-limit` states the bucket's compile-time
    default — operators can raise or lower a bucket at runtime, so treat the
    documented number as the baseline, not a contract. 429 responses carry
    `Retry-After` and `X-RateLimit-*`.

    ## Conventions

    - Prices are on the **0–100 cents scale** unless a field says otherwise
      (trader-analytics position/trade prices use the 0–1 scale; each field's
      description states its scale).
    - Errors: `{"detail": "<message>"}` for handler errors; FastAPI's
      standard validation envelope for 422s. Errors surfaced from a venue
      adapter instead use `{"error", "provider", "operation", "message"}` —
      see `DataProviderError`. Unhandled failures always return the generic
      500 body; internal details are logged, never returned.
    - Every request body is capped at 8 MiB service-wide (413).
  contact:
    name: Kairos
    url: https://app.kairos.trade/docs/api-reference
  termsOfService: https://kairos.trade/terms
servers:
  - url: https://data.kairos.trade
    description: Production
  - url: https://staging-data.kairos.trade
    description: Staging
security:
  - apiKeyClientId: []
    apiKeyKey: []
    apiKeySecret: []
paths:
  /matched-markets/enriched:
    get:
      tags:
        - Sports
      summary: Matched markets with identifiers, outcomes, and current reference prices
      description: >-
        Returns the same verified, live-filtered pair catalog as
        `/matched-markets`, with `details` and `pricing` attached to both sides.
        Unsupported markets, missing quotes, and individual venue failures
        produce `pricing: null` without changing pair membership or pagination.
        Prices use each venue's API scale and are reference prices, not
        executable bids or asks. The page is capped at 150 pairs to bound
        request cost. Responses are not cacheable.
      operationId: getEnrichedMatchedMarkets
      parameters:
        - name: limit
          in: query
          required: false
          description: Maximum number of enriched pairs to return.
          schema:
            type: integer
            minimum: 1
            maximum: 150
            default: 50
          example: 50
        - name: offset
          in: query
          required: false
          description: Legacy pagination offset. Do not combine with cursor.
          schema:
            type: integer
            minimum: 0
            default: 0
          example: 0
        - name: cursor
          in: query
          required: false
          description: >-
            Opaque keyset cursor. Send an empty value on the first page, then
            pass each response next_cursor. A 409 requires restarting the walk.
          schema:
            type: string
            maxLength: 16384
          example: ''
        - name: provider
          in: query
          required: false
          description: Filter to pairs where either side belongs to this provider.
          schema:
            type: string
          example: polymarket
        - name: min_similarity
          in: query
          required: false
          description: Minimum similarity, clamped server-side to at least 0.82.
          schema:
            type: number
            format: double
            minimum: 0
            maximum: 1
            default: 0.82
          example: 0.85
        - name: sort_by
          in: query
          required: false
          description: >-
            Offset-mode sort column. Cursor mode orders by canonical pair
            identity.
          schema:
            type: string
            enum:
              - similarity
              - updated_at
            default: similarity
        - name: include_total
          in: query
          required: false
          description: Include the total matching-pair count under pre-live filters.
          schema:
            type: boolean
            default: false
      responses:
        '200':
          description: >-
            A page of verified pairs with details and best-effort reference
            pricing.
          headers:
            Cache-Control:
              schema:
                type: string
                example: no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SportsEnrichedMatchedMarketsResponse'
        '400':
          description: >-
            Unknown provider, invalid cursor/sort, or cursor combined with a
            non-zero offset.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '409':
          description: >-
            The catalog changed during a cursor walk; restart with an empty
            cursor.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
        '422':
          $ref: '#/components/responses/DataValidationError'
        '429':
          $ref: '#/components/responses/DataRateLimited'
        '503':
          description: Matched-market or enrichment data could not be loaded.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
      security: []
components:
  schemas:
    SportsEnrichedMatchedMarketsResponse:
      allOf:
        - $ref: '#/components/schemas/SportsMatchedMarketsResponse'
        - type: object
          required:
            - pairs
          properties:
            pairs:
              type: array
              items:
                $ref: '#/components/schemas/SportsEnrichedMatchedMarketPair'
    SportsMatchedMarketsResponse:
      type: object
      required:
        - pairs
        - count
        - limit
        - offset
        - has_more
      properties:
        pairs:
          type: array
          items:
            $ref: '#/components/schemas/SportsMatchedMarketPair'
        count:
          type: integer
          description: >-
            Number of pairs on this page after live-status post-filtering (may
            be less than limit).
          example: 42
        limit:
          type: integer
          example: 50
        offset:
          type: integer
          example: 0
        has_more:
          type: boolean
          description: >-
            Whether the underlying page (before live-status post-filtering) was
            full — not a strict function of count.
        next_cursor:
          type:
            - string
            - 'null'
          description: >-
            Opaque cursor for the next keyset page. Present when cursor mode is
            requested.
        catalog_version:
          type: string
          description: Full-set fingerprint shared by every page in one cursor walk.
        total:
          type: integer
          description: >-
            Only present when include_total=true. Total matching-pair count
            under the pre-live-filter query filters.
          example: 1284
    SportsEnrichedMatchedMarketPair:
      allOf:
        - $ref: '#/components/schemas/SportsMatchedMarketPair'
        - type: object
          required:
            - a
            - b
          properties:
            a:
              $ref: '#/components/schemas/SportsEnrichedMatchedMarketSide'
            b:
              $ref: '#/components/schemas/SportsEnrichedMatchedMarketSide'
    SportsMatchedMarketPair:
      type: object
      required:
        - a
        - b
        - similarity
        - updated_at
      properties:
        a:
          $ref: '#/components/schemas/SportsMatchedMarketSide'
        b:
          $ref: '#/components/schemas/SportsMatchedMarketSide'
        similarity:
          type: number
          format: double
          minimum: 0.82
          maximum: 1
          example: 0.94
        updated_at:
          type: string
          format: date-time
    SportsEnrichedMatchedMarketSide:
      allOf:
        - $ref: '#/components/schemas/SportsMatchedMarketSide'
        - type: object
          required:
            - details
            - pricing
          properties:
            details:
              description: >-
                Indexed market identifiers and outcomes, or null when no market
                row resolves.
              oneOf:
                - $ref: '#/components/schemas/MarketsDetail'
                - type: 'null'
            pricing:
              description: >-
                Current venue reference price, or null when unsupported or
                unavailable.
              oneOf:
                - $ref: '#/components/schemas/MarketsPrice'
                - type: 'null'
    SportsMatchedMarketSide:
      type: object
      required:
        - provider_id
        - provider
        - market_id
        - title
        - ticker
        - image
        - icon
        - expires_at
        - category
      properties:
        provider_id:
          type: integer
          example: 2
        provider:
          type: string
          example: polymarket
        market_id:
          type: string
          example: '587234'
        title:
          type:
            - string
            - 'null'
          description: Null if metadata for this side's market isn't available.
          example: Will the Celtics win?
        ticker:
          type:
            - string
            - 'null'
        image:
          type:
            - string
            - 'null'
        icon:
          type:
            - string
            - 'null'
        expires_at:
          type:
            - string
            - 'null'
          format: date-time
        category:
          type:
            - string
            - 'null'
          description: >-
            Canonical title-cased category, or null when the market is
            uncategorised.
    MarketsDetail:
      type: object
      required:
        - market_id
        - provider_id
        - event_id
        - name
        - category
        - status
        - condition_id
        - token_id
        - token_ids
        - outcomes
      properties:
        market_id:
          type: string
        provider_id:
          type: integer
        event_id:
          type:
            - string
            - 'null'
        name:
          type:
            - string
            - 'null'
        category:
          type:
            - string
            - 'null'
        status:
          type:
            - string
            - 'null'
        condition_id:
          type:
            - string
            - 'null'
        token_id:
          type:
            - string
            - 'null'
        token_ids:
          type: array
          items:
            type: string
          description: Full provider token roster, aligned by index with outcomes.
        outcomes:
          type: array
          items:
            type: string
          description: Outcome labels aligned by index with token_ids.
    MarketsPrice:
      type: object
      required:
        - price
      properties:
        price:
          type: number
          description: >-
            Current venue reference price. Scale is venue-dependent and is not
            normalized.
        volume:
          type:
            - string
            - 'null'
        liquidity:
          type:
            - number
            - 'null'
  responses:
    DataValidationError:
      description: Request failed FastAPI parameter validation.
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
            properties:
              detail:
                type: array
                description: >-
                  One entry per failed field, with location, message, and error
                  type.
                items:
                  type: object
                  additionalProperties: true
    DataRateLimited:
      description: >
        Rate limit exceeded for this route's sliding window, keyed on the
        session `sub` when

        authenticated and on the trusted client IP otherwise. Honor
        `Retry-After`. A per-API-key

        data ceiling (set per credential) rejects with `{"detail": "API key data
        rate limit

        exceeded"}` instead of the `error` envelope below.
      headers:
        Retry-After:
          schema:
            type: integer
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: 'Rate limit exceeded: 100 per 1 minute'
  securitySchemes:
    apiKeyClientId:
      type: apiKey
      in: header
      name: X-Client-Id
      description: >-
        Credential client id (`kairos_ck_...`). Must be sent together with
        X-Api-Key and X-Api-Secret.
    apiKeyKey:
      type: apiKey
      in: header
      name: X-Api-Key
      description: 64-char hex API key.
    apiKeySecret:
      type: apiKey
      in: header
      name: X-Api-Secret
      description: 64-char hex API secret.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.