> ## 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.

# Ranked cross-venue links with a union book

> The cross-venue "matches" catalog: every approved global market link (one real-world contract listed on 2–4 venues) for which order execution asserts a union order book per side. Rows are ranked by the largest Discover hourly-volume score across their legs and paged by an opaque `cursor`. Served straight from the catalog cron's Redis keys, rebuilt every 60 s; empty until the first cycle after a deploy. Each leg's `executable` mirrors what `GET /orders/route-fees` on the execution API reports for that venue, so a row says which venues an order can be routed to and which are display-only.

Cached with `Cache-Control: public, max-age=15, s-maxage=30`.




## OpenAPI

````yaml /openapi/data-api.yaml get /market-links/featured
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:
  /market-links/featured:
    get:
      tags:
        - Markets
      summary: Ranked cross-venue links with a union book
      description: >
        The cross-venue "matches" catalog: every approved global market link
        (one real-world contract listed on 2–4 venues) for which order execution
        asserts a union order book per side. Rows are ranked by the largest
        Discover hourly-volume score across their legs and paged by an opaque
        `cursor`. Served straight from the catalog cron's Redis keys, rebuilt
        every 60 s; empty until the first cycle after a deploy. Each leg's
        `executable` mirrors what `GET /orders/route-fees` on the execution API
        reports for that venue, so a row says which venues an order can be
        routed to and which are display-only.


        Cached with `Cache-Control: public, max-age=15, s-maxage=30`.
      operationId: getFeaturedMarketLinks
      parameters:
        - name: limit
          in: query
          description: Rows per page.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: cursor
          in: query
          description: The previous page's `nextCursor`; omit for the first page.
          schema:
            type: string
            maxLength: 16
      responses:
        '200':
          description: One page of links in rank order.
          headers:
            Cache-Control:
              schema:
                type: string
                example: public, max-age=15, s-maxage=30
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketLinksFeaturedResponse'
        '400':
          description: A cursor this endpoint did not issue.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataError'
        '422':
          $ref: '#/components/responses/DataValidationError'
        '429':
          $ref: '#/components/responses/DataRateLimited'
        '503':
          description: The catalog store could not be read.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataError'
      security: []
components:
  schemas:
    MarketLinksFeaturedResponse:
      type: object
      required:
        - links
        - nextCursor
      properties:
        links:
          type: array
          items:
            $ref: '#/components/schemas/MarketLinkRow'
        nextCursor:
          type: string
          nullable: true
          description: Pass as `cursor` for the next page; null on the last page.
    DataError:
      type: object
      description: Handler error envelope (FastAPI HTTPException).
      required:
        - detail
      properties:
        detail:
          type: string
          description: Human-readable error message.
          example: Invalid provider
    MarketLinkRow:
      type: object
      description: One cross-venue link as the catalog publishes it.
      required:
        - id
        - title
        - image
        - league
        - sport
        - startTime
        - venues
        - syntheticIdYes
        - syntheticIdNo
        - executableVenues
        - rank
        - sideLabels
        - primary
      properties:
        id:
          type: string
          format: uuid
          description: The `MarketLink` id.
        title:
          type: string
          description: >-
            The event title from Discover's row for the primary venue, else the
            link's own title.
        image:
          type: string
          nullable: true
        league:
          type: string
          nullable: true
          description: >-
            League named by Discover's sports chip (e.g. `NFL`); null where the
            chip is the sport itself or the link is not sports.
        sport:
          type: string
          nullable: true
          description: Sport family (e.g. `Football`, `Soccer`).
        startTime:
          type: string
          format: date-time
          nullable: true
          description: >-
            Earliest leg expiration; venues close a game market at its scheduled
            start.
        slug:
          type: string
          description: The venue's game slug when Discover carries one; absent otherwise.
        venues:
          type: array
          minItems: 2
          maxItems: 4
          items:
            $ref: '#/components/schemas/MarketLinkVenue'
        syntheticIdYes:
          type: string
          description: >-
            Id of the union book for the link's YES side (`synthetic:<id>` on
            the stream).
        syntheticIdNo:
          type: string
        executableVenues:
          type: array
          items:
            type: string
          description: Providers whose legs are `executable`, in leg order.
        rank:
          type: number
          description: >-
            The largest Discover hourly-volume score across legs; the featured
            ordering key, never a displayed volume.
        sideLabels:
          type: object
          required:
            - 'yes'
            - 'no'
          properties:
            'yes':
              type: string
            'no':
              type: string
        primary:
          type: object
          required:
            - provider
            - marketId
          properties:
            provider:
              type: string
            marketId:
              type: string
          description: >-
            The leg whose Discover row supplied the title, else the first
            executable leg.
    MarketLinkVenue:
      type: object
      description: One venue's listing of a linked contract, in that venue's own keys.
      required:
        - provider
        - marketId
        - streamKey
        - tokenIdYes
        - tokenIdNo
        - executable
      properties:
        provider:
          type: string
          enum:
            - polymarket
            - predictfun
            - kalshi
            - hyperliquid
        marketId:
          type: string
          description: >-
            Executor-convention market id (Polymarket condition id, Predict.fun
            numeric id, Kalshi ticker, Hyperliquid outcome id).
        streamKey:
          type: string
          description: >-
            Stream-side id (Polymarket's numeric Gamma id; the market id
            elsewhere).
        marketIdNo:
          type: string
          description: >-
            The venue market that books the link's NO side where it is not
            `marketId` (Kalshi lists a game as one ticker per team). Present
            only on such legs.
        streamKeyNo:
          type: string
        tokenIdYes:
          type: string
          nullable: true
          description: >-
            The token the union book reads for the link's YES side on this
            venue.
        tokenIdNo:
          type: string
          nullable: true
        executable:
          type: boolean
          description: >-
            Whether `GET /orders/route-fees` reports this venue routable for the
            link; false for a display-only leg.
  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.