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

# Tournament bracket with live cross-provider prices per tie

> Builds a tournament bracket for `league`. Bracket structure and results are sourced from third-party sports-data providers depending on the league. Each tie/match is enriched with live prices from Polymarket, Kalshi (authenticated API), and Predict.fun where a corresponding market can be matched. `format=symmetric` (default) returns a left/right bracket converging on `final`, with an optional `thirdPlace` match and, for `format=groups-then-knockout`, a `groups` stage with standings tables. `format=left-to-right` instead returns all rounds in `leftRounds` with an empty `rightRounds`. `winner` is always null — this endpoint never resolves a champion. Responses are briefly cached.



## OpenAPI

````yaml /openapi/data-api.yaml get /sports/tournament-bracket
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:
  /sports/tournament-bracket:
    get:
      tags:
        - Sports
      summary: Tournament bracket with live cross-provider prices per tie
      description: >-
        Builds a tournament bracket for `league`. Bracket structure and results
        are sourced from third-party sports-data providers depending on the
        league. Each tie/match is enriched with live prices from Polymarket,
        Kalshi (authenticated API), and Predict.fun where a corresponding market
        can be matched. `format=symmetric` (default) returns a left/right
        bracket converging on `final`, with an optional `thirdPlace` match and,
        for `format=groups-then-knockout`, a `groups` stage with standings
        tables. `format=left-to-right` instead returns all rounds in
        `leftRounds` with an empty `rightRounds`. `winner` is always null — this
        endpoint never resolves a champion. Responses are briefly cached.
      operationId: getSportsTournamentBracket
      parameters:
        - name: league
          in: query
          required: true
          description: >-
            League slug, e.g. "ucl" (UEFA Champions League). Must resolve via a
            known league table.
          schema:
            type: string
          example: ucl
        - name: format
          in: query
          required: false
          description: >-
            Bracket layout. "symmetric" converges left/right rounds on a final;
            "left-to-right" is a single linear round list;
            "groups-then-knockout" adds a group stage.
          schema:
            type: string
            enum:
              - symmetric
              - left-to-right
              - groups-then-knockout
            default: symmetric
          example: symmetric
      responses:
        '200':
          description: >-
            Tournament bracket structure with live provider prices attached per
            tie.
          headers:
            Cache-Control:
              schema:
                type: string
                example: public, max-age=60, stale-while-revalidate=3600
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SportsTournamentBracketResponse'
        '422':
          $ref: '#/components/responses/DataValidationError'
        '429':
          $ref: '#/components/responses/DataRateLimited'
      security: []
components:
  schemas:
    SportsTournamentBracketResponse:
      type: object
      required:
        - leftRounds
        - rightRounds
        - final
        - winner
      properties:
        leftRounds:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketRound'
        rightRounds:
          type: array
          description: Empty when format=left-to-right.
          items:
            $ref: '#/components/schemas/SportsBracketRound'
        final:
          oneOf:
            - $ref: '#/components/schemas/SportsBracketMatch'
            - type: object
              description: Placeholder used when neither finalist is known yet.
              properties:
                id:
                  type: string
                  example: final-tbd
                teams:
                  type: array
                  items:
                    type: 'null'
                status:
                  type: string
                  example: scheduled
                subtitle:
                  type: string
                  example: Final
        winner:
          type: 'null'
          description: Always null — this endpoint never resolves a tournament champion.
        thirdPlace:
          oneOf:
            - $ref: '#/components/schemas/SportsBracketMatch'
            - type: 'null'
          description: Present only for competitions that have a third-place fixture.
        groups:
          type: array
          description: Present only when format=groups-then-knockout.
          items:
            $ref: '#/components/schemas/SportsBracketGroup'
    SportsBracketRound:
      type: object
      required:
        - name
        - shortName
        - matches
      properties:
        name:
          type: string
          example: Quarter-finals
        shortName:
          type: string
          example: QF
        matches:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketMatch'
    SportsBracketMatch:
      type: object
      required:
        - id
        - teams
        - status
        - subtitle
        - resolvesAfterExtraTime
      properties:
        id:
          type: string
          example: ucl-qf-1
        teams:
          type: array
          minItems: 2
          maxItems: 2
          items:
            oneOf:
              - $ref: '#/components/schemas/SportsBracketTeam'
              - type: 'null'
        status:
          type: string
          enum:
            - scheduled
            - live
            - completed
        subtitle:
          type: string
          description: Formatted fixture date, or "Date1 / Date2" for two-leg ties.
          example: Apr 9, 2026
        resolvesAfterExtraTime:
          type: boolean
        kickoffTime:
          type: string
          format: date-time
        matchday:
          type: integer
          example: 5
        scores:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type: integer
          example:
            - 2
            - 1
        winnerIdx:
          type: integer
          enum:
            - 0
            - 1
        aggregateScores:
          type: array
          description: Present for two-leg ties.
          minItems: 2
          maxItems: 2
          items:
            type: integer
          example:
            - 3
            - 2
        providerPrices:
          $ref: '#/components/schemas/SportsBracketProviderPrices'
    SportsBracketGroup:
      type: object
      required:
        - name
        - shortName
        - table
        - matches
      properties:
        name:
          type: string
          example: Group A
        shortName:
          type: string
          example: A
        table:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketStanding'
        matches:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketMatch'
    SportsBracketTeam:
      type: object
      required:
        - name
        - shortName
        - logo
      properties:
        name:
          type: string
          example: Real Madrid
        shortName:
          type: string
          example: RMA
        logo:
          type:
            - string
            - 'null'
    SportsBracketProviderPrices:
      type: object
      description: Only providers with a resolvable market for this tie are present.
      properties:
        polymarket:
          $ref: '#/components/schemas/SportsBracketProviderPricePoly'
        predictfun:
          $ref: '#/components/schemas/SportsBracketProviderPriceGeneric'
        kalshi:
          $ref: '#/components/schemas/SportsBracketProviderPriceKalshi'
    SportsBracketStanding:
      type: object
      required:
        - team
        - played
        - won
        - draw
        - lost
        - goalsFor
        - goalsAgainst
        - points
        - goalDifference
      properties:
        team:
          $ref: '#/components/schemas/SportsBracketTeam'
        played:
          type: integer
        won:
          type: integer
        draw:
          type: integer
        lost:
          type: integer
        goalsFor:
          type: integer
        goalsAgainst:
          type: integer
        points:
          type: integer
        goalDifference:
          type: integer
    SportsBracketProviderPricePoly:
      type: object
      required:
        - slug
        - marketId
        - title
        - titles
        - prices
        - drawPrice
        - outcomeMarketIds
      properties:
        slug:
          type: string
        marketId:
          type:
            - string
            - 'null'
        title:
          type: string
        titles:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type: string
        prices:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type:
              - number
              - 'null'
            format: double
        drawPrice:
          type:
            - number
            - 'null'
          format: double
        outcomeMarketIds:
          type: array
          minItems: 3
          maxItems: 3
          items:
            type:
              - string
              - 'null'
        spreadLines:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketSpreadLine'
        totalLines:
          type: array
          items:
            $ref: '#/components/schemas/SportsBracketTotalLine'
        comboEligibility:
          type: object
          description: Present only when the combo eligibility store has data for this tie.
          additionalProperties:
            $ref: '#/components/schemas/SportsComboEligibilityEntry'
    SportsBracketProviderPriceGeneric:
      type: object
      required:
        - slug
        - marketId
        - title
        - titles
        - prices
        - drawPrice
        - outcomeMarketIds
      properties:
        slug:
          type: string
        marketId:
          type:
            - string
            - 'null'
        title:
          type: string
        titles:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type: string
        prices:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type:
              - number
              - 'null'
            format: double
        drawPrice:
          type:
            - number
            - 'null'
          format: double
        outcomeMarketIds:
          type: array
          minItems: 3
          maxItems: 3
          items:
            type:
              - string
              - 'null'
    SportsBracketProviderPriceKalshi:
      type: object
      required:
        - eventTicker
        - marketId
        - title
        - titles
        - prices
        - drawPrice
        - outcomeMarketIds
      properties:
        eventTicker:
          type: string
        marketId:
          type:
            - string
            - 'null'
        title:
          type: string
        titles:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type: string
        prices:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type:
              - number
              - 'null'
            format: double
        drawPrice:
          type:
            - number
            - 'null'
          format: double
        outcomeMarketIds:
          type: array
          minItems: 3
          maxItems: 3
          items:
            type:
              - string
              - 'null'
    SportsBracketSpreadLine:
      type: object
      properties:
        line:
          type:
            - number
            - 'null'
          format: double
        team0Price:
          type:
            - number
            - 'null'
          format: double
        team1Price:
          type:
            - number
            - 'null'
          format: double
        team0MarketId:
          type:
            - string
            - 'null'
        team1MarketId:
          type:
            - string
            - 'null'
    SportsBracketTotalLine:
      type: object
      properties:
        line:
          type:
            - number
            - 'null'
          format: double
        overPrice:
          type:
            - number
            - 'null'
          format: double
        underPrice:
          type:
            - number
            - 'null'
          format: double
        overMarketId:
          type:
            - string
            - 'null'
        underMarketId:
          type:
            - string
            - 'null'
    SportsComboEligibilityEntry:
      type: object
      required:
        - yesPositionId
        - noPositionId
      properties:
        yesPositionId:
          type: string
        noPositionId:
          type: string
  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.