# Generated by live-intelligence/bin/generate-openapi.js — do not edit by hand.
# Paths come from the API route table and error codes from the error contract,
# so the specification cannot drift from the server.
openapi: 3.0.3
info:
  title: HelixOdds API
  version: v1
  description: |-
      Canonical sports markets and live match intelligence
      
      Every request is authenticated with a HelixOdds client token. Provider credentials are never sent on an API request: the account’s own provider credential is held encrypted and used only for upstream retrieval.
      
      Identifiers are opaque and stable. Provider identifiers appear under `provenance` and are not part of the contract.
      
      A socket transport delivers the `/changes` and `/live` contracts as they move. It is an accelerator over these routes, not a second contract, and is not modelled here because OpenAPI describes HTTP operations — see https://docs.helixodds.com/realtime.
  contact:
    name: HelixOdds support
    email: 'support@helixodds.com'
    url: 'https://docs.helixodds.com'
servers:
  - url: 'https://api.helixodds.com'
    description: Production
tags:
  - name: Service
    description: Status and contract.
  - name: Fixtures
    description: Processed fixtures and canonical markets.
  - name: Changes
    description: The incremental feed.
  - name: Live Intelligence
    description: In-play state and momentum.
  - name: Account
    description: 'Subscription, provider and usage.'
paths:
  '/api/v1/status':
    get:
      tags:
        - Service
      operationId: status
      summary: Service and account status
      description: 'Service identity and time. With a bearer token it also returns the account status and the health of the account’s processing.'
      security:
        - {}
        - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/StatusResponse'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/schema':
    get:
      tags:
        - Service
      operationId: schema
      summary: Machine-readable contract
      description: 'The vocabularies this API uses: products, features, statuses, capabilities, provenance types, change event types, error codes and the pagination limits actually enforced.'
      security:
        - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/SchemaResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/fixtures':
    get:
      tags:
        - Fixtures
      operationId: fixtures
      summary: List fixtures
      description: 'A page of the account’s processed fixtures, newest index first by opaque identifier. Use `cursor` to continue; the order is stable across processing cycles, so a cursor does not skip fixtures when the dataset is rewritten.'
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Page size. Default 50, maximum 200.'
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: cursor
          in: query
          required: false
          description: Opaque cursor from the previous page. Do not construct one.
          schema:
            type: string
        - name: league
          in: query
          required: false
          description: Case-insensitive substring match on the league name.
          schema:
            type: string
        - name: starts_after
          in: query
          required: false
          description: Only fixtures starting at or after this ISO-8601 instant.
          schema:
            type: string
            format: date-time
        - name: starts_before
          in: query
          required: false
          description: Only fixtures starting before this ISO-8601 instant.
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/FixtureListResponse'
        '400':
          description: 'INVALID_CURSOR, INVALID_PARAMETER.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/fixtures/{id}':
    get:
      tags:
        - Fixtures
      operationId: fixture
      summary: Read one fixture
      description: One fixture without its markets. Markets are a separate request because a single fixture can carry tens of kilobytes of them.
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/FixtureResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/fixtures/{id}/markets':
    get:
      tags:
        - Fixtures
      operationId: fixture_markets
      summary: 'List a fixture’s markets'
      description: 'Canonical markets and selections for one fixture, paginated.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
        - name: limit
          in: query
          required: false
          description: 'Page size. Default 50, maximum 200.'
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: cursor
          in: query
          required: false
          description: Opaque cursor from the previous page. Do not construct one.
          schema:
            type: string
        - name: market
          in: query
          required: false
          description: 'Canonical market name, for example TOTAL_GOALS.'
          schema:
            type: string
        - name: period
          in: query
          required: false
          description: 'Canonical period, for example FT or 1H.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/MarketListResponse'
        '400':
          description: 'INVALID_CURSOR, INVALID_PARAMETER.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/fixtures/{id}/markets/{market_id}':
    get:
      tags:
        - Fixtures
      operationId: fixture_market
      summary: Read one market
      description: 'A single market on a fixture, addressed by its opaque market id or by its canonical market name.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
        - name: market_id
          in: path
          required: true
          description: 'Opaque market identifier, prefixed mk_, or a canonical market name.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/MarketResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: 'FIXTURE_NOT_FOUND, MARKET_NOT_FOUND.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/changes':
    get:
      tags:
        - Changes
      operationId: changes
      summary: Read changes since a cursor
      description: 'The incremental feed. Each event carries a monotonic `seq`; store the last one processed and pass it as `cursor`. The window is bounded: a cursor older than retention returns `INVALID_CURSOR`, which means re-read the fixture list rather than accept a gap.'
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Page size. Default 50, maximum 200.'
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: cursor
          in: query
          required: false
          description: Opaque cursor from the previous page. Do not construct one.
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/ChangeListResponse'
        '400':
          description: 'INVALID_CURSOR, INVALID_PARAMETER.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/live':
    get:
      tags:
        - Live Intelligence
      operationId: live
      summary: List live fixtures
      description: 'Fixtures currently in play for this account, with momentum.'
      security:
        - bearerAuth: []
      parameters:
        - name: limit
          in: query
          required: false
          description: 'Page size. Default 50, maximum 200.'
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 50
        - name: cursor
          in: query
          required: false
          description: Opaque cursor from the previous page. Do not construct one.
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/LiveListResponse'
        '400':
          description: 'INVALID_CURSOR, INVALID_PARAMETER.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/live/{id}':
    get:
      tags:
        - Live Intelligence
      operationId: live_fixture
      summary: Read one live fixture
      description: 'The live state of one fixture: clock, score, visual state and momentum.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/LiveFixtureResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, FEATURE_NOT_ENABLED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/live/{id}/timeline':
    get:
      tags:
        - Live Intelligence
      operationId: live_timeline
      summary: 'Read a live fixture’s timeline'
      description: 'Discrete changes of live state, with the time each was observed.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/LiveTimelineResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, FEATURE_NOT_ENABLED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/live/{id}/momentum':
    get:
      tags:
        - Live Intelligence
      operationId: live_momentum
      summary: 'Read a live fixture’s momentum'
      description: 'Momentum for one fixture. When it cannot be computed the reason is returned instead of a number — a neutral value that means “unknown” is indistinguishable from one that means “balanced”.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/LiveMomentumResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, FEATURE_NOT_ENABLED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/live/{id}/stats':
    get:
      tags:
        - Live Intelligence
      operationId: live_stats
      summary: 'Read a live fixture’s statistical breakdown'
      description: 'The per-minute series and per-period totals. Requires the `advanced_stats` add-on.'
      security:
        - bearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          description: 'Opaque fixture identifier, prefixed fx_.'
          schema:
            type: string
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/LiveStatsResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED, FEATURE_NOT_ENABLED, ORIGIN_NOT_ALLOWED, SUBSCRIPTION_REQUIRED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '404':
          description: FIXTURE_NOT_FOUND.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '409':
          description: PROVIDER_NOT_CONNECTED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '503':
          description: DATA_NOT_READY.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/account':
    get:
      tags:
        - Account
      operationId: account
      summary: Read the account
      description: 'Products, features, expiry, provider status and health. Available whatever the subscription state, so an account whose subscription lapsed can still see that it lapsed.'
      security:
        - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/AccountResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/account/provider':
    get:
      tags:
        - Account
      operationId: account_provider
      summary: Read the provider connection
      description: 'The status of the account’s own provider credential, as a hint and a status. The credential itself is never returned by any endpoint.'
      security:
        - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/AccountProviderResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
  '/api/v1/account/usage':
    get:
      tags:
        - Account
      operationId: account_usage
      summary: Read usage counters
      description: 'Request and provider-call counters. These are telemetry: they are buffered and flushed periodically, and are not billing records.'
      security:
        - bearerAuth: []
      parameters: []
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/AccountUsageResponse'
        '401':
          description: INVALID_API_TOKEN.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '403':
          description: 'CLIENT_REVOKED, CLIENT_SUSPENDED.'
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '429':
          description: RATE_LIMITED.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
        '500':
          description: INTERNAL_ERROR.
          content:
            application/json:
              schema:
                '$ref': '#/components/schemas/Error'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Your HelixOdds client token.
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              enum:
                - BAD_REQUEST
                - CLIENT_REVOKED
                - CLIENT_SUSPENDED
                - CONFLICT
                - DATA_NOT_READY
                - FEATURE_NOT_ENABLED
                - FIXTURE_NOT_FOUND
                - INTERNAL_ERROR
                - INVALID_API_TOKEN
                - INVALID_CURSOR
                - INVALID_PARAMETER
                - MARKET_NOT_FOUND
                - METHOD_NOT_ALLOWED
                - NOT_FOUND
                - ORIGIN_NOT_ALLOWED
                - PROVIDER_NOT_CONNECTED
                - RATE_LIMITED
                - REQUEST_TOO_LARGE
                - SERVICE_UNAVAILABLE
                - SUBSCRIPTION_REQUIRED
                - UPSTREAM_UNAVAILABLE
              description: 'Frozen. Branch on this, not on the message.'
            message:
              type: string
              description: For a human reading a log. May be reworded between releases.
            request_id:
              type: string
              nullable: true
              description: Quote this when reporting a problem.
    Pagination:
      type: object
      properties:
        limit:
          type: integer
        next_cursor:
          type: string
          nullable: true
          description: Opaque. Null on the last page.
        has_more:
          type: boolean
    Freshness:
      type: object
      description: 'When the data was retrieved upstream and when it was processed. `provider_fetched_at` moves only after a real provider retrieval.'
      properties:
        provider_fetched_at:
          type: string
          format: date-time
          nullable: true
        processed_at:
          type: string
          format: date-time
          nullable: true
        published_at:
          type: string
          format: date-time
          nullable: true
        age_ms:
          type: integer
          nullable: true
    Health:
      type: object
      properties:
        status:
          type: string
          enum:
            - HEALTHY
            - DEGRADED
            - DOWN
            - UNCONFIGURED
        checked_at:
          type: string
          format: date-time
        components:
          type: array
          items:
            type: object
            properties:
              component:
                type: string
                enum:
                  - market_engine
                  - live_intelligence
                  - provider_connection
              status:
                type: string
                enum:
                  - HEALTHY
                  - DEGRADED
                  - DOWN
                  - UNCONFIGURED
              code:
                type: string
                nullable: true
              last_success_at:
                type: string
                format: date-time
                nullable: true
              age_ms:
                type: integer
                nullable: true
    Fixture:
      type: object
      properties:
        fixture_id:
          type: string
          description: 'Opaque, prefixed fx_. Stable.'
        home:
          type: string
          nullable: true
        away:
          type: string
          nullable: true
        league:
          type: string
          nullable: true
        starts_at:
          type: string
          format: date-time
          nullable: true
        market_count:
          type: integer
        provenance:
          type: object
          description: 'Where the fixture came from. Not part of the contract: do not key your integration on a provider identifier.'
          properties:
            source_provider:
              type: string
              nullable: true
            provider_fixture_id:
              type: string
    Market:
      type: object
      properties:
        market_id:
          type: string
          description: 'Opaque, prefixed mk_.'
        market:
          type: string
          nullable: true
          description: Canonical market name.
        market_name:
          type: string
          nullable: true
        period:
          type: string
          nullable: true
        sections:
          type: array
          items:
            type: string
        lines:
          type: array
          items: {}
        origin_type:
          type: string
          enum:
            - RAW
            - MAPPED
            - DERIVED
            - COMPOSED
          description: 'MAPPED when a canonical identity was established; RAW when the market exists upstream and no canonical identity was proven. DERIVED and COMPOSED are reserved and not emitted in v1.'
        derivation:
          type: object
          properties:
            version:
              type: string
        selection_count:
          type: integer
        selections:
          type: array
          items:
            type: object
            properties:
              selection_id:
                type: string
                nullable: true
                description: 'Opaque, prefixed sl_.'
              selection:
                type: string
                nullable: true
              line:
                type: string
                nullable: true
              qualifier:
                type: string
                nullable: true
              odds:
                type: object
                properties:
                  fractional:
                    type: string
                    nullable: true
                  decimal:
                    type: number
                    nullable: true
              dimension:
                type: string
                nullable: true
              subject:
                type: string
                nullable: true
              subject_2:
                type: string
                nullable: true
              grid:
                type: object
                nullable: true
              quality:
                type: object
                properties:
                  status:
                    type: string
                    nullable: true
                  publishable:
                    type: boolean
                  reasons:
                    type: array
                    items:
                      type: string
              provenance:
                type: object
                properties:
                  provider_selection_id:
                    type: string
                    nullable: true
        provenance:
          type: object
          properties:
            provider_market_ids:
              type: array
              items:
                type: string
    Selection:
      type: object
      properties:
        selection_id:
          type: string
          nullable: true
          description: 'Opaque, prefixed sl_.'
        selection:
          type: string
          nullable: true
        line:
          type: string
          nullable: true
        qualifier:
          type: string
          nullable: true
        odds:
          type: object
          properties:
            fractional:
              type: string
              nullable: true
            decimal:
              type: number
              nullable: true
        dimension:
          type: string
          nullable: true
        subject:
          type: string
          nullable: true
        subject_2:
          type: string
          nullable: true
        grid:
          type: object
          nullable: true
        quality:
          type: object
          properties:
            status:
              type: string
              nullable: true
            publishable:
              type: boolean
            reasons:
              type: array
              items:
                type: string
        provenance:
          type: object
          properties:
            provider_selection_id:
              type: string
              nullable: true
    StatusResponse:
      type: object
      properties:
        service:
          type: object
          properties:
            name:
              type: string
            products:
              type: object
            urls:
              type: object
            support_email:
              type: string
            api_version:
              type: string
        api_version:
          type: string
        status:
          type: string
        time:
          type: string
          format: date-time
        account:
          type: object
          nullable: true
          properties:
            client_id:
              type: string
            status:
              type: string
              enum:
                - ACTIVE
                - SUSPENDED
                - REVOKED
        health:
          '$ref': '#/components/schemas/Health'
    SchemaResponse:
      type: object
      properties:
        api_version:
          type: string
        products:
          type: array
          items:
            type: string
            enum:
              - market_engine
              - live_intelligence
        features:
          type: object
        base_features:
          type: object
        client_statuses:
          type: array
          items:
            type: string
        provider_statuses:
          type: array
          items:
            type: string
            enum:
              - UNCONFIGURED
              - VERIFYING
              - CONNECTED
              - DEGRADED
              - INVALID_CREDENTIAL
              - DISABLED
        provider_capabilities:
          type: array
          items:
            type: string
            enum:
              - prematch
              - live_odds
              - live_stats
              - timeline
              - player_events
        health_statuses:
          type: array
          items:
            type: string
        origin_types:
          type: array
          items:
            type: string
        derivation_version:
          type: string
        change_event_types:
          type: array
          items:
            type: string
            enum:
              - fixture_markets_updated
              - fixture_removed
        error_codes:
          type: array
          items:
            type: string
        pagination:
          type: object
        freshness_fields:
          type: array
          items:
            type: string
        identity:
          type: object
    FixtureListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              fixture_id:
                type: string
                description: 'Opaque, prefixed fx_. Stable.'
              home:
                type: string
                nullable: true
              away:
                type: string
                nullable: true
              league:
                type: string
                nullable: true
              starts_at:
                type: string
                format: date-time
                nullable: true
              market_count:
                type: integer
              provenance:
                type: object
                description: 'Where the fixture came from. Not part of the contract: do not key your integration on a provider identifier.'
                properties:
                  source_provider:
                    type: string
                    nullable: true
                  provider_fixture_id:
                    type: string
        pagination:
          '$ref': '#/components/schemas/Pagination'
        meta:
          allOf:
            - '$ref': '#/components/schemas/Freshness'
            - type: object
              properties:
                fixture_count:
                  type: integer
                filtered_count:
                  type: integer
                source_provider:
                  type: string
                  nullable: true
                index_stale:
                  type: boolean
    FixtureResponse:
      type: object
      properties:
        data:
          allOf:
            - type: object
              properties:
                fixture_id:
                  type: string
                  description: 'Opaque, prefixed fx_. Stable.'
                home:
                  type: string
                  nullable: true
                away:
                  type: string
                  nullable: true
                league:
                  type: string
                  nullable: true
                starts_at:
                  type: string
                  format: date-time
                  nullable: true
                market_count:
                  type: integer
                provenance:
                  type: object
                  description: 'Where the fixture came from. Not part of the contract: do not key your integration on a provider identifier.'
                  properties:
                    source_provider:
                      type: string
                      nullable: true
                    provider_fixture_id:
                      type: string
            - type: object
              properties:
                markets_url:
                  type: string
                bet_builder_available:
                  type: boolean
        meta:
          '$ref': '#/components/schemas/Freshness'
    MarketListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              market_id:
                type: string
                description: 'Opaque, prefixed mk_.'
              market:
                type: string
                nullable: true
                description: Canonical market name.
              market_name:
                type: string
                nullable: true
              period:
                type: string
                nullable: true
              sections:
                type: array
                items:
                  type: string
              lines:
                type: array
                items: {}
              origin_type:
                type: string
                enum:
                  - RAW
                  - MAPPED
                  - DERIVED
                  - COMPOSED
                description: 'MAPPED when a canonical identity was established; RAW when the market exists upstream and no canonical identity was proven. DERIVED and COMPOSED are reserved and not emitted in v1.'
              derivation:
                type: object
                properties:
                  version:
                    type: string
              selection_count:
                type: integer
              selections:
                type: array
                items:
                  type: object
                  properties:
                    selection_id:
                      type: string
                      nullable: true
                      description: 'Opaque, prefixed sl_.'
                    selection:
                      type: string
                      nullable: true
                    line:
                      type: string
                      nullable: true
                    qualifier:
                      type: string
                      nullable: true
                    odds:
                      type: object
                      properties:
                        fractional:
                          type: string
                          nullable: true
                        decimal:
                          type: number
                          nullable: true
                    dimension:
                      type: string
                      nullable: true
                    subject:
                      type: string
                      nullable: true
                    subject_2:
                      type: string
                      nullable: true
                    grid:
                      type: object
                      nullable: true
                    quality:
                      type: object
                      properties:
                        status:
                          type: string
                          nullable: true
                        publishable:
                          type: boolean
                        reasons:
                          type: array
                          items:
                            type: string
                    provenance:
                      type: object
                      properties:
                        provider_selection_id:
                          type: string
                          nullable: true
              provenance:
                type: object
                properties:
                  provider_market_ids:
                    type: array
                    items:
                      type: string
        pagination:
          '$ref': '#/components/schemas/Pagination'
        meta:
          allOf:
            - '$ref': '#/components/schemas/Freshness'
            - type: object
              properties:
                fixture_id:
                  type: string
                market_count:
                  type: integer
    MarketResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            market_id:
              type: string
              description: 'Opaque, prefixed mk_.'
            market:
              type: string
              nullable: true
              description: Canonical market name.
            market_name:
              type: string
              nullable: true
            period:
              type: string
              nullable: true
            sections:
              type: array
              items:
                type: string
            lines:
              type: array
              items: {}
            origin_type:
              type: string
              enum:
                - RAW
                - MAPPED
                - DERIVED
                - COMPOSED
              description: 'MAPPED when a canonical identity was established; RAW when the market exists upstream and no canonical identity was proven. DERIVED and COMPOSED are reserved and not emitted in v1.'
            derivation:
              type: object
              properties:
                version:
                  type: string
            selection_count:
              type: integer
            selections:
              type: array
              items:
                type: object
                properties:
                  selection_id:
                    type: string
                    nullable: true
                    description: 'Opaque, prefixed sl_.'
                  selection:
                    type: string
                    nullable: true
                  line:
                    type: string
                    nullable: true
                  qualifier:
                    type: string
                    nullable: true
                  odds:
                    type: object
                    properties:
                      fractional:
                        type: string
                        nullable: true
                      decimal:
                        type: number
                        nullable: true
                  dimension:
                    type: string
                    nullable: true
                  subject:
                    type: string
                    nullable: true
                  subject_2:
                    type: string
                    nullable: true
                  grid:
                    type: object
                    nullable: true
                  quality:
                    type: object
                    properties:
                      status:
                        type: string
                        nullable: true
                      publishable:
                        type: boolean
                      reasons:
                        type: array
                        items:
                          type: string
                  provenance:
                    type: object
                    properties:
                      provider_selection_id:
                        type: string
                        nullable: true
            provenance:
              type: object
              properties:
                provider_market_ids:
                  type: array
                  items:
                    type: string
        meta:
          '$ref': '#/components/schemas/Freshness'
    ChangeListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              seq:
                type: integer
                description: Monotonic. Store the last one you processed.
              type:
                type: string
                enum:
                  - fixture_markets_updated
                  - fixture_removed
              fixture_id:
                type: string
              published_at:
                type: string
                format: date-time
              cycle_id:
                type: string
              provenance:
                type: object
                properties:
                  provider_fixture_id:
                    type: string
        pagination:
          '$ref': '#/components/schemas/Pagination'
        meta:
          type: object
          properties:
            window:
              type: object
              properties:
                first_seq:
                  type: integer
                  nullable: true
                last_seq:
                  type: integer
                  nullable: true
            retained_events:
              type: integer
    LiveListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
        pagination:
          '$ref': '#/components/schemas/Pagination'
        meta:
          type: object
          properties:
            live_fixture_count:
              type: integer
            provider_fetched_at:
              type: string
              format: date-time
              nullable: true
            processed_at:
              type: string
              format: date-time
              nullable: true
            age_ms:
              type: integer
              nullable: true
    LiveFixtureResponse:
      type: object
      properties:
        data:
          type: object
        meta:
          type: object
    LiveTimelineResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            fixture_id:
              type: string
            timeline:
              type: array
              items:
                type: object
        meta:
          type: object
    LiveMomentumResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            fixture_id:
              type: string
            momentum:
              type: object
              nullable: true
            unavailable_reason:
              type: string
              nullable: true
              description: 'Set when momentum could not be computed. Non-null means `momentum` must not be read as a value.'
            statistics_url:
              type: string
        meta:
          type: object
    LiveStatsResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            fixture_id:
              type: string
            series:
              type: object
              nullable: true
            periods:
              type: object
              nullable: true
        meta:
          type: object
    AccountResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            client_id:
              type: string
            name:
              type: string
            status:
              type: string
              enum:
                - ACTIVE
                - SUSPENDED
                - REVOKED
            api_token_prefix:
              type: string
              description: A prefix only. The token itself is never returned.
            allowed_origins:
              type: array
              items:
                type: string
            products:
              type: array
              items:
                type: object
                properties:
                  product:
                    type: string
                    enum:
                      - market_engine
                      - live_intelligence
                  display_name:
                    type: string
                  active:
                    type: boolean
                  expires_at:
                    type: string
                    format: date-time
                    nullable: true
                  reason:
                    type: string
                    nullable: true
            features:
              type: object
            provider:
              type: object
              nullable: true
            health:
              '$ref': '#/components/schemas/Health'
        meta:
          type: object
    AccountProviderResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            connection:
              type: object
              nullable: true
              properties:
                provider:
                  type: string
                status:
                  type: string
                  enum:
                    - UNCONFIGURED
                    - VERIFYING
                    - CONNECTED
                    - DEGRADED
                    - INVALID_CREDENTIAL
                    - DISABLED
                credential_hint:
                  type: object
                  nullable: true
                  description: A length and the last four characters. Never the credential.
                  properties:
                    length:
                      type: integer
                    last4:
                      type: string
                      nullable: true
                capabilities:
                  type: object
                rate_limit:
                  type: object
                verified_at:
                  type: string
                  format: date-time
                  nullable: true
                last_success_at:
                  type: string
                  format: date-time
                  nullable: true
                last_error_at:
                  type: string
                  format: date-time
                  nullable: true
                last_error_code:
                  type: string
                  nullable: true
            health:
              type: object
        meta:
          type: object
    AccountUsageResponse:
      type: object
      properties:
        data:
          type: object
          properties:
            client_id:
              type: string
            totals:
              type: object
            today:
              type: object
            this_month:
              type: object
            last_request_at:
              type: string
              format: date-time
              nullable: true
            last_status:
              type: integer
              nullable: true
            daily:
              type: object
            monthly:
              type: object
        meta:
          type: object
          properties:
            contract:
              type: string
              enum:
                - telemetry
            note:
              type: string
            retention:
              type: object
    Envelope:
      type: object
      properties:
        data:
          type: object
        meta:
          type: object
security:
  - bearerAuth: []
