openapi: 3.1.0
info:
  title: YM Trading API - Market Maker Pilot
  version: 2.0.0
  description: Curated participant-facing contract for approved YM API-trading pilots. Implemented
    pilot capabilities are distinct from roadmap notes in the accompanying handbook. This
    specification is not a service-level agreement. Contract activation is environment-specific;
    confirm v2 availability with YM before sending commands.
servers:
  - url: https://ympredictions.com
    description: Production
paths:
  /v1/categories:
    get:
      summary: Canonical top-level prediction-market categories
      responses:
        "200":
          description: Public canonical categories from the active taxonomy registry
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalTaxonomyListResponse"
  /v1/taxonomy:
    get:
      summary: Canonical public taxonomy hierarchy
      responses:
        "200":
          description: Public taxonomy nodes with explicit parent references
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalTaxonomyListResponse"
  /v1/tags:
    get:
      summary: Orthogonal public event-discovery tags
      parameters:
        - in: query
          name: category
          required: false
          schema:
            type: string
        - in: query
          name: q
          required: false
          schema:
            type: string
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Tags; tags are facets and never semantic parents
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalTagListResponse"
  /v1/series:
    get:
      summary: Canonical recurring series nodes
      responses:
        "200":
          description: Public series nodes from the active taxonomy registry
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalTaxonomyListResponse"
  /v1/sports:
    get:
      summary: Canonical sports taxonomy nodes
      responses:
        "200":
          description: Public sport nodes from the active taxonomy registry
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalTaxonomyListResponse"
  /v1/competitions:
    get:
      summary: Canonical sports competitions
      parameters:
        - in: query
          name: sport
          required: false
          schema:
            type: string
        - in: query
          name: q
          required: false
          schema:
            type: string
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Public competitions with immutable entity ids and parent references
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCompetitionListResponse"
  /v1/events:
    get:
      summary: Canonical event-first market discovery
      description: |
        The recommended discovery entry point. Results use immutable YM ids,
        human slugs, explicit parent references, public revisions, and opaque
        keyset cursors. Offset pagination is deliberately unsupported.
      parameters:
        - in: query
          name: category
          required: false
          schema:
            type: string
          description: Comma-separated canonical category keys.
        - in: query
          name: sport
          required: false
          schema:
            type: string
        - in: query
          name: competition
          required: false
          schema:
            type: string
        - in: query
          name: series
          required: false
          schema:
            type: string
        - in: query
          name: cycle
          required: false
          schema:
            type: string
        - in: query
          name: phase
          required: false
          schema:
            type: string
        - in: query
          name: tag
          required: false
          schema:
            type: string
          description: Comma-separated tag ids or slugs.
        - in: query
          name: status
          required: false
          schema:
            type: string
          description: Comma-separated lifecycle statuses or public aliases (`active`,`pending`,`resolved`).
        - in: query
          name: q
          required: false
          schema:
            type: string
        - in: query
          name: start_min
          required: false
          schema:
            type: string
            format: date-time
        - in: query
          name: start_max
          required: false
          schema:
            type: string
            format: date-time
        - in: query
          name: close_min
          required: false
          schema:
            type: string
            format: date-time
        - in: query
          name: close_max
          required: false
          schema:
            type: string
            format: date-time
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Supports `families`, `families.markets`, and explicit `external_mappings`.
        - in: query
          name: cursor
          required: false
          schema:
            type: string
          description: Opaque `next_cursor` from the preceding page.
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
      responses:
        "200":
          description: Canonical event page
          headers:
            ETag:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalEventListResponse"
        "304":
          description: Representation matches `If-None-Match`.
        "400":
          description: Invalid filter, include, timestamp, status, cursor, or unsupported offset.
  /v1/events/{eventID}:
    get:
      summary: Canonical event detail by immutable id, current slug, or permanent alias
      parameters:
        - in: path
          name: eventID
          required: true
          schema:
            type: string
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Supports `families`, `families.markets`, and explicit `external_mappings`.
      responses:
        "200":
          description: Canonical event detail. `Content-Location` contains the current canonical route.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalEventResponse"
        "404":
          description: Event not found.
  /v1/events/{eventID}/market-families:
    get:
      summary: Canonical market families nested under an event
      parameters:
        - in: path
          name: eventID
          required: true
          schema:
            type: string
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Supports `families.markets` and explicit `external_mappings`.
      responses:
        "200":
          description: Event-scoped canonical market families
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalFamilyListResponse"
        "404":
          description: Event not found.
  /v1/events/{eventID}/market-families/{familyID}:
    get:
      summary: Canonical event-scoped market-family detail
      parameters:
        - in: path
          name: eventID
          required: true
          schema:
            type: string
        - in: path
          name: familyID
          required: true
          schema:
            type: string
          description: Immutable family id, current slug, or permanent alias within the event.
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Provider ids require explicit `external_mappings`.
      responses:
        "200":
          description: Canonical family with leaf markets and current `Content-Location`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalFamilyResponse"
        "404":
          description: Event or market family not found.
  /v1/market-families:
    get:
      summary: Grouped market discovery with legacy or canonical hierarchy view
      parameters:
        - in: query
          name: view
          required: false
          schema:
            type: string
            enum:
              - legacy
              - canonical
          description: Use `canonical` for immutable identity, revisions, and canonical routes. Omission
            preserves the legacy response during migration.
        - in: query
          name: event
          required: false
          schema:
            type: string
          description: Canonical view only; filter by immutable event id, slug, or permanent alias.
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Canonical view only; supports `families.markets` and `external_mappings`.
        - in: query
          name: cursor
          required: false
          schema:
            type: string
          description: Canonical view only; opaque keyset cursor. Offset pagination is unsupported.
        - in: query
          name: status
          required: false
          schema:
            type: string
          description: Optional comma-separated family statuses (`active`,`resolved`,`pending`)
        - in: query
          name: category
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case category filter
        - in: query
          name: entity_id
          required: false
          schema:
            type: string
          description: Optional canonical sports entity id filter
        - in: query
          name: entity_slug
          required: false
          schema:
            type: string
          description: Optional canonical sports entity slug filter
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Market families
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/MarketFamilyListResponse"
                  - $ref: "#/components/schemas/CanonicalDirectFamilyListResponse"
        "400":
          description: Invalid canonical filter, include, status, cursor, or unsupported offset.
  /v1/market-families/feed:
    get:
      summary: Windowed and paginated market-family discovery feed
      parameters:
        - in: query
          name: status
          required: false
          schema:
            type: string
          description: Optional comma-separated family statuses (`active`,`closed`,`resolved`,`pending`)
        - in: query
          name: category
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case category filter
        - in: query
          name: country
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case country filter
        - in: query
          name: entity_id
          required: false
          schema:
            type: string
          description: Optional canonical sports entity id filter
        - in: query
          name: entity_slug
          required: false
          schema:
            type: string
          description: Optional canonical sports entity slug filter
        - in: query
          name: q
          required: false
          schema:
            type: string
          description: Optional case-insensitive search over title, description, and outcome names
        - in: query
          name: sort
          required: false
          schema:
            type: string
            enum:
              - default
              - volume
              - newest
              - ending
              - probability
              - movers
          description: Optional feed sort
        - in: query
          name: window
          required: false
          schema:
            type: string
            enum:
              - all
              - featured
              - live
              - upcoming
              - resolved_recent
          description: Optional discovery window
        - in: query
          name: cursor
          required: false
          schema:
            type: string
          description: Opaque cursor for the next page
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
      responses:
        "200":
          description: Paginated market-family feed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MarketFamilyFeedResponse"
  /v1/market-families/{familyID}:
    get:
      summary: Market family detail with legacy or canonical hierarchy view
      parameters:
        - in: path
          name: familyID
          required: true
          schema:
            type: string
        - in: query
          name: view
          required: false
          schema:
            type: string
            enum:
              - legacy
              - canonical
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Canonical view only; provider ids require explicit `external_mappings`.
      responses:
        "200":
          description: Market family detail
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/MarketFamilyResponse"
                  - $ref: "#/components/schemas/CanonicalFamilyResponse"
        "400":
          description: Ambiguous family slug or invalid canonical include.
        "404":
          description: Market family not found
  /v1/markets:
    get:
      summary: Public market catalog with legacy quote view or canonical hierarchy view
      parameters:
        - in: query
          name: view
          required: false
          schema:
            type: string
            enum:
              - legacy
              - canonical
          description: Use `canonical` for immutable event/family identity, revision, and canonical-route
            fields. Omission preserves the legacy response during migration.
        - in: query
          name: event
          required: false
          schema:
            type: string
          description: Canonical view only; immutable event id, current slug, or permanent event alias.
        - in: query
          name: family
          required: false
          schema:
            type: string
          description: Canonical view only; immutable family id or an event-scoped family slug/alias.
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Canonical view only; comma-separated expansion list. Provider ids require explicit
            `external_mappings`.
        - in: query
          name: cursor
          required: false
          schema:
            type: string
          description: Canonical view only; opaque keyset cursor. Offset pagination is unsupported.
        - in: query
          name: status
          required: false
          schema:
            type: string
          description: Optional comma-separated lifecycle filter. Supports raw backend statuses and frontend
            aliases (`active`,`pending`,`resolved`).
        - in: query
          name: category
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case category filter.
        - in: query
          name: country
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case country filter.
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Markets
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/LegacyMarketListResponse"
                  - $ref: "#/components/schemas/CanonicalMarketListResponse"
        "400":
          description: Invalid canonical filter, include, status, cursor, or unsupported offset.
  /v1/markets/summary:
    get:
      summary: Public market catalog summary for headers and lightweight dashboards
      parameters:
        - in: query
          name: category
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case category filter.
        - in: query
          name: country
          required: false
          schema:
            type: string
          description: Optional comma-separated lower-case country filter.
      responses:
        "200":
          description: Market catalog summary
          content:
            application/json:
              schema:
                type: object
                required:
                  - summary
                  - source
                properties:
                  summary:
                    type: object
                    required:
                      - total_markets
                      - total_volume_24h
                      - total_liquidity
                      - active_traders_24h
                      - generated_at
                    properties:
                      total_markets:
                        type: integer
                      total_volume_24h:
                        type: number
                      total_liquidity:
                        type: number
                      active_traders_24h:
                        type: integer
                      generated_at:
                        type: string
                        format: date-time
                  source:
                    type: string
  /v1/markets/{marketID}:
    get:
      summary: Public market detail with legacy quote or canonical hierarchy fields
      parameters:
        - in: path
          name: marketID
          required: true
          schema:
            type: string
        - in: query
          name: view
          required: false
          schema:
            type: string
            enum:
              - legacy
              - canonical
          description: Use `canonical` for immutable event/family identity, revision, and canonical URL.
        - in: query
          name: include
          required: false
          schema:
            type: string
          description: Canonical view only; provider ids require explicit `external_mappings`.
      responses:
        "200":
          description: Market detail
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/LegacyMarket"
                  - $ref: "#/components/schemas/CanonicalMarketResponse"
        "400":
          description: Invalid canonical include.
        "404":
          description: Market not found
  /v1/book:
    get:
      summary: Book snapshot by query params
      parameters:
        - in: query
          name: market_id
          required: true
          schema:
            type: string
        - in: query
          name: depth
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 20
          description: Maximum price levels returned per side. Values above 200 are capped at 200.
      responses:
        "200":
          description: Book
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BookSnapshot"
  /v1/markets/{marketID}/book:
    get:
      summary: L2 book snapshot
      parameters:
        - in: path
          name: marketID
          required: true
          schema:
            type: string
        - in: query
          name: depth
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 20
          description: Maximum price levels returned per side. Values above 200 are capped at 200.
      responses:
        "200":
          description: Book
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BookSnapshot"
  /v1/markets/{marketID}/stats:
    get:
      summary: Market statistics derived from settled fills and open holds
      parameters:
        - in: path
          name: marketID
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Market stats
          content:
            application/json:
              schema:
                type: object
                required:
                  - market_id
                  - volume_24h
                  - total_volume
                  - traders_count_24h
                  - trades_count_24h
                  - avg_position_24h
                  - open_interest
                properties:
                  market_id:
                    type: string
                  volume_24h:
                    type: number
                  total_volume:
                    type: number
                  traders_count_24h:
                    type: integer
                  trades_count_24h:
                    type: integer
                  avg_position_24h:
                    type: number
                  open_interest:
                    type: number
  /v1/markets/{marketID}/trades:
    get:
      summary: Recent taker-side market trades
      parameters:
        - in: path
          name: marketID
          required: true
          schema:
            type: string
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
      responses:
        "200":
          description: Recent trades
          content:
            application/json:
              schema:
                type: object
                required:
                  - market_id
                  - count
                  - trades
                properties:
                  market_id:
                    type: string
                  count:
                    type: integer
                  trades:
                    type: array
                    items:
                      type: object
                      required:
                        - trade_id
                        - market_id
                        - user_id
                        - username
                        - counterparty_user_id
                        - side
                        - liquidity_role
                        - price
                        - price_cents
                        - quantity
                        - occurred_at
                      properties:
                        trade_id:
                          type: string
                        market_id:
                          type: string
                        user_id:
                          type: string
                          description: Pseudonymous participant identifier
                        username:
                          type: string
                          description: Pseudonymous display identifier
                        counterparty_user_id:
                          type: string
                          description: Pseudonymous participant identifier for the opposite side
                        side:
                          type: string
                          enum:
                            - BUY
                            - SELL
                        liquidity_role:
                          type: string
                          enum:
                            - TAKER
                            - MAKER
                        price:
                          type: number
                        price_cents:
                          type: integer
                        quantity:
                          type: integer
                        occurred_at:
                          type: string
                          format: date-time
  /v1/orders:
    get:
      summary: List the authenticated participant's canonical orders
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:read
      parameters:
        - in: query
          name: market_id
          required: false
          schema:
            type: string
        - in: query
          name: execution_status
          required: false
          schema:
            type: string
            enum:
              - PENDING
              - WORKING
              - PARTIALLY_FILLED
              - FILLED
              - CANCELLED
              - EXPIRED
              - REJECTED
        - in: query
          name: pending_action
          required: false
          schema:
            type: string
            enum:
              - NONE
              - REPLACE
              - CANCEL
        - in: query
          name: state_quality
          required: false
          schema:
            type: string
            enum:
              - CONFIRMED
              - RECONCILIATION_REQUIRED
        - in: query
          name: cursor
          required: false
          description: Opaque newest-first keyset cursor returned by the prior page.
          schema:
            type: string
        - in: query
          name: limit
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
      responses:
        "200":
          description: Stable newest-first canonical order page
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderListResponse"
        "400":
          description: Invalid canonical filter or cursor
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
        "503":
          description: One or more selected orders require reconciliation before canonical read cutover
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
    post:
      summary: Admit a canonical order command
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:write
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            maxLength: 200
            pattern: ^(?![Yy][Mm]:).+$
          description: Participant-scoped command identity; the `ym:` prefix is reserved for internal commands.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrderRequest"
      responses:
        "200":
          description: Exact scoped idempotent replay with the original command result and current order
            snapshot
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
        "201":
          description: Command admitted atomically with a PENDING canonical order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
              example:
                schema_version: 2
                command:
                  command_id: 9b1b889c-2fd3-46d6-bc55-441afc7a7cc8
                  order_id: 3bdb9f66-402e-4f06-9bc7-74026c004317
                  command_sequence: 1
                  command_type: NEW
                  client_request_id: mm-new-no-000001
                  client_order_id: strategy-no-000001
                  admission_status: ADMITTED
                  outcome_status: PENDING
                  admitted_at: 2026-09-02T10:00:00Z
                  created_at: 2026-09-02T10:00:00Z
                  updated_at: 2026-09-02T10:00:00Z
                order:
                  id: 3bdb9f66-402e-4f06-9bc7-74026c004317
                  created_by_command_id: 9b1b889c-2fd3-46d6-bc55-441afc7a7cc8
                  client_order_id: strategy-no-000001
                  market_id: example-market
                  market_generation: 7
                  action: BUY
                  outcome: NO
                  price_cents: 35
                  original_quantity: 10
                  total_quantity: 10
                  cumulative_filled_quantity: 0
                  remaining_unfilled_quantity: 10
                  working_quantity: 0
                  filled_notional_cents: 0
                  execution_status: PENDING
                  pending_action: null
                  state_quality: CONFIRMED
                  order_version: 1
                  is_terminal: false
                  is_working: false
                  may_still_execute: true
                  has_reserved_exposure: true
                  time_in_force: GTC
                  admitted_at: 2026-09-02T10:00:00Z
                  updated_at: 2026-09-02T10:00:00Z
                idempotent_replay: false
        "400":
          description: Invalid command
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
        "409":
          description: Stale generation, idempotency conflict, command conflict, or unavailable market state
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
        "503":
          description: Temporarily unavailable admission dependency
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
  /v1/orders/{orderID}:
    get:
      summary: Get order
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:read
      parameters:
        - in: path
          name: orderID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Current authoritative canonical order snapshot
          headers:
            ETag:
              description: Derived from order_version; accepted by If-None-Match.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "304":
          description: The supplied ETag matches the current order version
        "503":
          description: The order requires canonical reconciliation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
  /v1/orders/{orderID}/replace:
    post:
      summary: Admit a canonical single-order replacement command
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:write
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            maxLength: 200
            pattern: ^(?![Yy][Mm]:).+$
        - in: path
          name: orderID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReplaceOrderRequest"
      responses:
        "200":
          description: Exact idempotent replay of the original replacement result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
        "202":
          description: Replacement admitted; the prior price and quantity remain effective until DX confirms
            REPLACED
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
        "409":
          description: Version conflict, no-op replacement, insufficient exposure, or another mutation is
            pending
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
  /v1/orders/{orderID}/cancel:
    post:
      summary: Admit a canonical cancel command
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:write
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
            maxLength: 200
            pattern: ^(?![Yy][Mm]:).+$
          description: Participant-scoped command identity; the `ym:` prefix is reserved for internal commands.
        - in: path
          name: orderID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Cancel is already effective locally or is an idempotent completed/no-op result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
        "202":
          description: Venue-directed cancel admitted; order truth retains its prior execution status with
            pending_action=CANCEL
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalCommandOrderResponse"
        "409":
          description: Idempotency conflict or another mutation command is already pending
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
        "503":
          description: Order requires reconciliation before a safe cancel decision
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CanonicalOrderError"
  /v1/trading-feed:
    get:
      summary: Open the resumable private order and execution WebSocket feed
      description: This endpoint serves Private Order & Execution Feed v2. A v1 cursor cannot resume v2;
        after durably completing v1 through the announced boundary, begin with a cursorless
        snapshot. That snapshot replaces only nonterminal state and does not replay v1 terminal
        orders or fills. The gateway authenticates the bearer token and signs participant identity
        to the dedicated private-trading-feed service. Identity is never selected by query string.
        Without a cursor the stream sends a consistent nonterminal snapshot before live events. With
        a cursor it resumes at-least-once delivery after the last client-applied event. WebSocket
        compression is disabled for this low-latency profile. The route is absent until
        PRIVATE_TRADING_FEED_ENABLED is explicitly enabled after the documented durability, replica,
        retention, and canonical-readiness rollout gates pass.
      security:
        - bearerAuth: []
      x-required-scopes:
        - trading-feed:read
      parameters:
        - in: query
          name: cursor
          required: false
          description: Opaque signed last-applied cursor from this participant's prior session.
          schema:
            type: string
      responses:
        "101":
          description: WebSocket protocol switch; message schemas are documented by x-private-trading-feed
            below.
        "401":
          description: Missing or invalid bearer authentication
        "403":
          description: Missing trading-feed scope or disallowed browser Origin
        "503":
          description: Private feed unavailable
  /v1/positions:
    get:
      summary: List user positions (YES/NO exposure projection)
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:read
      parameters:
        - in: query
          name: user_id
          required: false
          schema:
            type: string
        - in: query
          name: market_id
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Positions listed
          content:
            application/json:
              schema:
                type: object
                required:
                  - user_id
                  - count
                  - positions
                properties:
                  user_id:
                    type: string
                  count:
                    type: integer
                  positions:
                    type: array
                    items:
                      type: object
                      required:
                        - market_id
                        - yes_shares
                        - no_shares
                        - avg_yes_price
                        - avg_no_price
                        - mark_yes_price
                        - mark_no_price
                        - unrealized_pnl
                        - realized_pnl
                        - market
                      properties:
                        market_id:
                          type: string
                        yes_shares:
                          type: integer
                        no_shares:
                          type: integer
                        avg_yes_price:
                          type: number
                        avg_no_price:
                          type: number
                        mark_yes_price:
                          type: number
                        mark_no_price:
                          type: number
                        unrealized_pnl:
                          type: number
                        realized_pnl:
                          type: number
                        market:
                          type: object
                          required:
                            - market_id
                            - title
                            - description
                            - status
                            - settlement_currency
                            - updated_at
                            - metadata
                          properties:
                            market_id:
                              type: string
                            title:
                              type: string
                            description:
                              type: string
                            status:
                              type: string
                              enum:
                                - DRAFT
                                - OPEN
                                - SUSPENDED
                                - RESOLVED
                                - CLOSED
                            settlement_currency:
                              type: string
                            close_at:
                              type: string
                              format: date-time
                              nullable: true
                            resolve_at:
                              type: string
                              format: date-time
                              nullable: true
                            resolved_outcome:
                              type: string
                              nullable: true
                            updated_at:
                              type: string
                              format: date-time
                              nullable: true
                            metadata:
                              type: object
                              additionalProperties: true
  /v1/portfolio:
    get:
      summary: User portfolio summary and positions
      security:
        - bearerAuth: []
      x-required-scopes:
        - orders:read
      parameters:
        - in: query
          name: user_id
          required: false
          schema:
            type: string
        - in: query
          name: market_id
          required: false
          schema:
            type: string
      responses:
        "200":
          description: Portfolio summary
          content:
            application/json:
              schema:
                type: object
                required:
                  - user_id
                  - total_value
                  - total_pnl
                  - pnl_percent
                  - positions
                properties:
                  user_id:
                    type: string
                  total_value:
                    type: number
                  total_pnl:
                    type: number
                  pnl_percent:
                    type: number
                  positions:
                    type: array
                    items:
                      type: object
                      required:
                        - market_id
                        - yes_shares
                        - no_shares
                        - avg_yes_price
                        - avg_no_price
                        - mark_yes_price
                        - mark_no_price
                        - unrealized_pnl
                        - realized_pnl
                        - market
                      properties:
                        market_id:
                          type: string
                        yes_shares:
                          type: integer
                        no_shares:
                          type: integer
                        avg_yes_price:
                          type: number
                        avg_no_price:
                          type: number
                        mark_yes_price:
                          type: number
                        mark_no_price:
                          type: number
                        unrealized_pnl:
                          type: number
                        realized_pnl:
                          type: number
                        market:
                          type: object
                          required:
                            - market_id
                            - title
                            - description
                            - status
                            - settlement_currency
                            - updated_at
                            - metadata
                          properties:
                            market_id:
                              type: string
                            title:
                              type: string
                            description:
                              type: string
                            status:
                              type: string
                              enum:
                                - DRAFT
                                - OPEN
                                - SUSPENDED
                                - RESOLVED
                                - CLOSED
                            settlement_currency:
                              type: string
                            close_at:
                              type: string
                              format: date-time
                              nullable: true
                            resolve_at:
                              type: string
                              format: date-time
                              nullable: true
                            resolved_outcome:
                              type: string
                              nullable: true
                            updated_at:
                              type: string
                              format: date-time
                              nullable: true
                            metadata:
                              type: object
                              additionalProperties: true
  /v1/accounts/{userID}/balances:
    get:
      summary: User balances (derived from immutable postings)
      security:
        - bearerAuth: []
      x-required-scopes:
        - balances:read
      parameters:
        - in: path
          name: userID
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Balances
components:
  schemas:
    CanonicalTaxonomyListResponse:
      type: object
      additionalProperties: false
      required:
        - count
        - source
      properties:
        taxonomy:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTaxonomyNode"
        categories:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTaxonomyNode"
        series:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTaxonomyNode"
        sports:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTaxonomyNode"
        count:
          type: integer
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalTagListResponse:
      type: object
      additionalProperties: false
      required:
        - tags
        - count
        - source
      properties:
        tags:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTag"
        count:
          type: integer
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalCompetitionListResponse:
      type: object
      additionalProperties: false
      required:
        - competitions
        - count
        - source
      properties:
        competitions:
          type: array
          items:
            type: object
            additionalProperties: true
        count:
          type: integer
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalEventListResponse:
      type: object
      additionalProperties: false
      required:
        - events
        - count
        - limit
        - has_more
        - next_cursor
        - source
      properties:
        events:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalEvent"
        count:
          type: integer
        limit:
          type: integer
        has_more:
          type: boolean
        next_cursor:
          type: string
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalEventResponse:
      type: object
      additionalProperties: false
      required:
        - event
        - alias_used
        - source
      properties:
        event:
          $ref: "#/components/schemas/CanonicalEvent"
        alias_used:
          type: boolean
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalFamilyListResponse:
      type: object
      additionalProperties: false
      required:
        - event_id
        - market_families
        - count
        - source
      properties:
        event_id:
          type: string
        market_families:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalMarketFamily"
        count:
          type: integer
        source:
          type: string
          enum:
            - canonical_catalog
    CanonicalFamilyResponse:
      type: object
      additionalProperties: false
      required:
        - market_family
        - alias_used
        - source
      properties:
        market_family:
          $ref: "#/components/schemas/CanonicalMarketFamily"
        alias_used:
          type: boolean
        source:
          type: string
          enum:
            - canonical_catalog
    MarketFamilyListResponse:
      type: object
      required:
        - families
        - count
        - cached
        - source
      properties:
        families:
          type: array
          items:
            $ref: "#/components/schemas/MarketFamily"
        count:
          type: integer
        cached:
          type: boolean
        source:
          type: string
    CanonicalDirectFamilyListResponse:
      type: object
      additionalProperties: false
      required:
        - market_families
        - count
        - limit
        - has_more
        - next_cursor
        - source
      properties:
        market_families:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalMarketFamily"
        count:
          type: integer
        limit:
          type: integer
        has_more:
          type: boolean
        next_cursor:
          type: string
        source:
          type: string
          enum:
            - canonical_catalog
    MarketFamilyFeedResponse:
      type: object
      required:
        - families
        - count
        - total_count
        - limit
        - has_more
        - cached
        - source
      properties:
        families:
          type: array
          items:
            $ref: "#/components/schemas/MarketFamily"
        count:
          type: integer
        total_count:
          type: integer
        limit:
          type: integer
        next_cursor:
          type: string
        has_more:
          type: boolean
        window:
          type: string
        cached:
          type: boolean
        source:
          type: string
    MarketFamilyResponse:
      type: object
      required:
        - family
        - source
      properties:
        family:
          $ref: "#/components/schemas/MarketFamily"
        source:
          type: string
    LegacyMarketListResponse:
      type: object
      required:
        - markets
        - count
        - cached
        - source
      properties:
        markets:
          type: array
          items:
            $ref: "#/components/schemas/LegacyMarket"
        count:
          type: integer
        cached:
          type: boolean
        source:
          type: string
    CanonicalMarketListResponse:
      type: object
      additionalProperties: false
      required:
        - markets
        - count
        - limit
        - has_more
        - next_cursor
        - source
      properties:
        markets:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalMarket"
        count:
          type: integer
        limit:
          type: integer
        has_more:
          type: boolean
        next_cursor:
          type: string
        source:
          type: string
          enum:
            - canonical_catalog
    LegacyMarket:
      type: object
      required:
        - market_id
        - market_generation
        - title
        - description
        - status
        - settlement_currency
        - updated_at
        - metadata
      properties:
        market_id:
          type: string
        market_generation:
          type: integer
          format: int64
          minimum: 0
          description: Current activation generation used to fence order commands. A zero value means the
            market is not activation-managed and cannot be submitted through the canonical order
            path.
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
            - DRAFT
            - OPEN
            - SUSPENDED
            - RESOLVED
            - CLOSED
        settlement_currency:
          type: string
        close_at:
          type: string
          format: date-time
          nullable: true
        resolve_at:
          type: string
          format: date-time
          nullable: true
        resolved_outcome:
          type: string
          nullable: true
        publication_state:
          $ref: "#/components/schemas/MarketPublicationState"
        presentation_renderer:
          $ref: "#/components/schemas/MarketPresentationRenderer"
        live_data_policy:
          $ref: "#/components/schemas/MarketLiveDataPolicy"
        liveDetails:
          $ref: "#/components/schemas/LivePresentationSnapshot"
        updated_at:
          type: string
          format: date-time
        metadata:
          type: object
          additionalProperties: true
        best_bid:
          type: number
        best_ask:
          type: number
        last_price:
          type: number
        volume_24h:
          type: number
        total_volume:
          type: number
        open_interest:
          type: number
        seq:
          type: integer
    CanonicalMarketResponse:
      type: object
      additionalProperties: false
      required:
        - market
        - source
      properties:
        market:
          $ref: "#/components/schemas/CanonicalMarket"
        source:
          type: string
          enum:
            - canonical_catalog
    BookSnapshot:
      type: object
      required:
        - market_id
        - depth
        - bids
        - asks
        - seq
        - updated_at
      properties:
        market_id:
          type: string
        depth:
          type: integer
          minimum: 1
          maximum: 200
        bids:
          type: array
          items:
            $ref: "#/components/schemas/BookLevel"
        asks:
          type: array
          items:
            $ref: "#/components/schemas/BookLevel"
        seq:
          type: integer
          format: int64
          description: YM projection sequence; not a durable professional replay cursor.
        updated_at:
          type: string
          format: date-time
          description: YM projection timestamp, not a venue-origin timestamp.
    CanonicalOrderListResponse:
      type: object
      additionalProperties: false
      required:
        - schema_version
        - count
        - orders
        - next_cursor
      properties:
        schema_version:
          type: integer
          const: 2
        count:
          type: integer
          minimum: 0
        orders:
          type: array
          items:
            $ref: "#/components/schemas/Order"
        next_cursor:
          type: string
          description: Empty when no later page exists.
    CanonicalOrderError:
      type: object
      required:
        - code
        - message
        - retryable
      properties:
        code:
          type: string
        message:
          type: string
        error:
          type: string
          deprecated: true
          description: Transitional alias for message.
        command_id:
          type:
            - string
            - "null"
          format: uuid
        client_request_id:
          type:
            - string
            - "null"
        admission_status:
          type: string
          enum:
            - ADMITTED
            - REJECTED
          description: Present when the response recovered or persisted a canonical command.
        outcome_status:
          type: string
          enum:
            - PENDING
            - EFFECTIVE
            - REJECTED
            - NOOP
            - CANCELLED_BEFORE_DISPATCH
            - UNKNOWN
          description: Present when the response recovered or persisted a canonical command.
        idempotent_replay:
          type: boolean
          description: Present when a canonical command identity was recovered.
        retryable:
          type: boolean
        details:
          type: object
          additionalProperties: true
    CreateOrderRequest:
      allOf:
        - $ref: "#/components/schemas/CreateOrderFields"
      unevaluatedProperties: false
    CanonicalCommandOrderResponse:
      type: object
      additionalProperties: false
      required:
        - schema_version
        - command
        - idempotent_replay
      properties:
        schema_version:
          type: integer
          const: 2
        command:
          $ref: "#/components/schemas/CanonicalOrderCommand"
        order:
          $ref: "#/components/schemas/Order"
        idempotent_replay:
          type: boolean
    Order:
      type: object
      additionalProperties: false
      required:
        - id
        - created_by_command_id
        - market_id
        - market_generation
        - action
        - outcome
        - price_cents
        - original_quantity
        - total_quantity
        - cumulative_filled_quantity
        - remaining_unfilled_quantity
        - working_quantity
        - filled_notional_cents
        - execution_status
        - pending_action
        - state_quality
        - order_version
        - is_terminal
        - is_working
        - may_still_execute
        - has_reserved_exposure
        - admitted_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        created_by_command_id:
          type: string
          format: uuid
        client_order_id:
          type: string
        market_id:
          type: string
        market_generation:
          type: integer
          format: int64
          minimum: 1
          description: Exact positive market-generation admission fence.
        action:
          type: string
          enum:
            - BUY
            - SELL
          description: Immutable participant action against outcome; SELL is position-reducing only.
        outcome:
          type: string
          enum:
            - YES
            - NO
          description: Immutable economic outcome. Price and filled notional fields use this outcome's
            coordinate.
        price_cents:
          type: integer
          format: int64
          minimum: 0
          maximum: 100
          description: Effective limit price of the named outcome, in cents.
        original_quantity:
          type: integer
          format: int64
          minimum: 1
        total_quantity:
          type: integer
          format: int64
          minimum: 1
          description: Latest venue-effective total quantity; original_quantity remains the immutable NEW size.
        cumulative_filled_quantity:
          type: integer
          format: int64
          minimum: 0
        remaining_unfilled_quantity:
          type: integer
          format: int64
          minimum: 0
        working_quantity:
          type: integer
          format: int64
          minimum: 0
        filled_notional_cents:
          type: integer
          format: int64
          minimum: 0
          description: Sum of fill price times quantity in the named outcome coordinate.
        execution_status:
          type: string
          enum:
            - PENDING
            - WORKING
            - PARTIALLY_FILLED
            - FILLED
            - CANCELLED
            - EXPIRED
            - REJECTED
        pending_action:
          type:
            - string
            - "null"
          enum:
            - REPLACE
            - CANCEL
            - null
        state_quality:
          type: string
          enum:
            - CONFIRMED
            - RECONCILIATION_REQUIRED
        order_version:
          type: integer
          format: int64
          minimum: 1
        is_terminal:
          type: boolean
        is_working:
          type: boolean
        may_still_execute:
          type: boolean
        has_reserved_exposure:
          type: boolean
        time_in_force:
          type: string
          enum:
            - GTC
            - IOC
            - DAY
        admitted_at:
          type: string
          format: date-time
        venue_accepted_at:
          type:
            - string
            - "null"
          format: date-time
        last_fill_at:
          type:
            - string
            - "null"
          format: date-time
        terminal_at:
          type:
            - string
            - "null"
          format: date-time
        terminal_reason:
          type: string
        updated_at:
          type: string
          format: date-time
    ReplaceOrderRequest:
      type: object
      additionalProperties: false
      required:
        - expected_order_version
        - price_cents
        - total_quantity
      properties:
        expected_order_version:
          type: integer
          format: int64
          minimum: 1
          description: Optimistic concurrency fence from the latest canonical order snapshot.
        price_cents:
          type: integer
          format: int64
          minimum: 0
          maximum: 100
          description: Replacement price in the order's immutable outcome coordinate.
        total_quantity:
          type: integer
          format: int64
          minimum: 1
          description: Target total quantity including any quantity already filled.
    PrivateFeedLifecycleEvent:
      type: object
      additionalProperties: false
      description: Order lifecycle events carry a complete order snapshot. The sole orderless variant is
        order.command_result for an authenticated, schema-valid NEW command rejected by YM before an
        order exists; that variant carries the canonical command and no order, fill, or venue
        fields.
      required:
        - schema_version
        - cursor
        - event_id
        - event_type
        - account_scope
        - cause
        - ym_received_at
        - ym_projected_at
        - server_sent_at
      allOf:
        - if:
            properties:
              event_type:
                const: order.command_result
            required:
              - event_type
          then:
            required:
              - command
            oneOf:
              - required:
                  - order_id
                  - order_version
                  - order
              - properties:
                  command:
                    allOf:
                      - $ref: "#/components/schemas/CanonicalOrderCommand"
                      - type: object
                        required:
                          - command_type
                          - admission_status
                          - outcome_status
                        properties:
                          command_type:
                            const: NEW
                          admission_status:
                            const: REJECTED
                          outcome_status:
                            const: REJECTED
                not:
                  anyOf:
                    - required:
                        - order_id
                    - required:
                        - order_version
                    - required:
                        - order
                    - required:
                        - fill
                    - required:
                        - venue
                    - required:
                        - venue_event_at
          else:
            required:
              - order_id
              - order_version
              - order
            not:
              required:
                - command
        - if:
            properties:
              event_type:
                const: order.fill
            required:
              - event_type
          then:
            required:
              - fill
          else:
            not:
              required:
                - fill
      properties:
        schema_version:
          type: integer
          const: 2
        cursor:
          type: string
          description: Persist only after the client fully validates and applies this event.
        event_id:
          type: string
          format: uuid
        event_type:
          type: string
          enum:
            - order.admitted
            - order.working
            - order.replaced
            - order.fill
            - order.cancelled
            - order.expired
            - order.rejected
            - order.command_result
        account_scope:
          type: string
          const: self
        order_id:
          type: string
          format: uuid
        order_version:
          type: integer
          format: int64
          minimum: 1
        cause:
          $ref: "#/components/schemas/PrivateFeedCause"
        venue:
          $ref: "#/components/schemas/PrivateFeedVenueEvidence"
        venue_event_at:
          type: string
          format: date-time
        ym_received_at:
          type: string
          format: date-time
        ym_projected_at:
          type: string
          format: date-time
        server_sent_at:
          type: string
          format: date-time
        command:
          allOf:
            - $ref: "#/components/schemas/CanonicalOrderCommand"
          description: Present on order.command_result and omitted on other lifecycle events. A rejected NEW
            may omit order_id when admission failed before any order existed.
        order:
          $ref: "#/components/schemas/Order"
        fill:
          $ref: "#/components/schemas/PrivateFeedFill"
    PrivateFeedControlMessage:
      type: object
      additionalProperties: false
      required:
        - schema_version
        - type
        - server_sent_at
      properties:
        schema_version:
          type: integer
          const: 2
        type:
          type: string
          enum:
            - stream.welcome
            - stream.snapshot_started
            - stream.snapshot_chunk
            - stream.snapshot_completed
            - stream.ready
            - stream.heartbeat
            - stream.error
        server_sent_at:
          type: string
          format: date-time
        contract:
          type: string
          const: Private Order & Execution Feed v2
        heartbeat_seconds:
          type: integer
          minimum: 1
        max_frame_bytes:
          type: integer
          minimum: 1
        delivery:
          type: string
          const: at_least_once
        snapshot_id:
          type: string
          format: uuid
        as_of_cursor:
          type: string
        scope:
          type: string
          const: NONTERMINAL
        order_count:
          type: integer
          minimum: 0
        orders:
          type: array
          maxItems: 100
          items:
            $ref: "#/components/schemas/Order"
        code:
          type: string
          enum:
            - CURSOR_EXPIRED
            - REPLAY_LIMIT_EXCEEDED
            - INVALID_CURSOR
            - SLOW_CONSUMER
            - STREAM_ERROR
        message:
          type: string
        last_written_cursor:
          type: string
    CanonicalTaxonomyNode:
      type: object
      additionalProperties: false
      required:
        - id
        - node_key
        - kind
        - category
        - label
        - slug
        - path
        - depth
        - sort_order
        - registry_version
        - canonical_url
      properties:
        id:
          type: string
        node_key:
          type: string
        parent_id:
          type: string
        kind:
          type: string
        group_kind:
          type: string
        category:
          type: string
        label:
          type: string
        slug:
          type: string
        path:
          type: string
        depth:
          type: integer
        sort_order:
          type: integer
        registry_version:
          type: string
        canonical_url:
          type: string
        metadata:
          type: object
          additionalProperties: true
    CanonicalTag:
      type: object
      additionalProperties: false
      required:
        - id
        - slug
        - label
        - event_count
      properties:
        id:
          type: string
        slug:
          type: string
        label:
          type: string
        category:
          type: string
        event_count:
          type: integer
          format: int64
        metadata:
          type: object
          additionalProperties: true
    CanonicalEvent:
      type: object
      additionalProperties: false
      required:
        - id
        - slug
        - title
        - description
        - status
        - classification_status
        - classification_source
        - taxonomy
        - tags
        - revision
        - updated_at
        - canonical_url
      properties:
        id:
          type: string
        slug:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          type: string
        classification_status:
          type: string
        classification_source:
          type: string
        starts_at:
          type: string
          format: date-time
        close_at:
          type: string
          format: date-time
        resolve_at:
          type: string
          format: date-time
        taxonomy:
          $ref: "#/components/schemas/CanonicalEventTaxonomy"
        tags:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTag"
        revision:
          type: integer
          format: int64
        updated_at:
          type: string
          format: date-time
        canonical_url:
          type: string
        live:
          $ref: "#/components/schemas/LivePresentationSnapshot"
        market_families:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalMarketFamily"
    CanonicalMarketFamily:
      type: object
      additionalProperties: false
      required:
        - id
        - event_id
        - slug
        - title
        - description
        - family_type_key
        - family_code
        - selection_mode
        - membership_complete
        - status
        - display_order
        - revision
        - updated_at
        - canonical_url
      properties:
        id:
          type: string
        event_id:
          type: string
        slug:
          type: string
        title:
          type: string
        description:
          type: string
        family_type_key:
          type: string
        family_code:
          type: string
        selection_mode:
          type: string
        resolution_cardinality:
          type: string
        resolution_coordination:
          type: string
        resolution_constraint_key:
          type: string
        membership_complete:
          type: boolean
        status:
          type: string
        display_order:
          type: integer
        close_at:
          type: string
          format: date-time
        resolve_at:
          type: string
          format: date-time
        resolved_selection_key:
          type: string
        revision:
          type: integer
          format: int64
        updated_at:
          type: string
          format: date-time
        canonical_url:
          type: string
        publication_state:
          $ref: "#/components/schemas/MarketPublicationState"
        presentation_renderer:
          $ref: "#/components/schemas/MarketPresentationRenderer"
        live_data_policy:
          $ref: "#/components/schemas/MarketLiveDataPolicy"
        live:
          $ref: "#/components/schemas/LivePresentationSnapshot"
        markets:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalMarket"
    MarketFamily:
      type: object
      required:
        - id
        - title
        - description
        - category
        - status
        - outcomes
        - totalVolume
        - volume24h
        - liquidity
        - endDate
      properties:
        id:
          type: string
        eventId:
          type: string
        eventTitle:
          type: string
        eventStatus:
          type: string
        verticalKey:
          type: string
        pathPatternId:
          type: string
        providerName:
          type: string
        providerEventRef:
          type: string
        classificationStatus:
          type: string
        classificationSource:
          type: string
        title:
          type: string
        description:
          type: string
        category:
          type: string
        status:
          type: string
          enum:
            - active
            - resolved
            - pending
        familyStatus:
          type: string
        familyTypeKey:
          type: string
        familyCode:
          type: string
        selectionMode:
          type: string
        displayOrder:
          type: integer
        canonicalSlug:
          type: string
        canonicalUrl:
          type: string
        publicationState:
          $ref: "#/components/schemas/MarketPublicationState"
        presentationRenderer:
          $ref: "#/components/schemas/MarketPresentationRenderer"
        liveDataPolicy:
          $ref: "#/components/schemas/MarketLiveDataPolicy"
        liveDetails:
          $ref: "#/components/schemas/LivePresentationSnapshot"
        outcomes:
          type: array
          items:
            $ref: "#/components/schemas/MarketFamilyOutcome"
        totalVolume:
          type: number
        volume24h:
          type: number
        liquidity:
          type: number
        endDate:
          type: string
        imageUrl:
          type: string
    CanonicalMarket:
      type: object
      additionalProperties: false
      required:
        - id
        - family_id
        - event_id
        - title
        - description
        - status
        - market_generation
        - settlement_currency
        - selection_key
        - outcome_id
        - outcome_name
        - sort_order
        - revision
        - updated_at
        - canonical_url
      properties:
        id:
          type: string
        family_id:
          type: string
        event_id:
          type: string
        title:
          type: string
        description:
          type: string
        status:
          type: string
        market_generation:
          type: integer
          format: int64
          minimum: 0
          description: Exact current admission fence for canonical order entry. A zero value means this public
            market is not available through the generation-fenced canonical order contract; refresh
            the market after any stale_market_generation response.
        settlement_currency:
          type: string
        selection_key:
          type: string
        outcome_id:
          type: string
        outcome_name:
          type: string
        sort_order:
          type: integer
        close_at:
          type: string
          format: date-time
        resolve_at:
          type: string
          format: date-time
        resolved_outcome:
          type: string
        revision:
          type: integer
          format: int64
        updated_at:
          type: string
          format: date-time
        canonical_url:
          type: string
        publication_state:
          $ref: "#/components/schemas/MarketPublicationState"
        presentation_renderer:
          $ref: "#/components/schemas/MarketPresentationRenderer"
        live_data_policy:
          $ref: "#/components/schemas/MarketLiveDataPolicy"
        live:
          $ref: "#/components/schemas/LivePresentationSnapshot"
        external_mappings:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalExternalMapping"
    MarketPublicationState:
      type: string
      enum:
        - HIDDEN_BLOCKED
        - PUBLIC_BLOCKED
        - PUBLIC_OPEN
        - PUBLIC_DEGRADED
        - RETIRED
    MarketPresentationRenderer:
      type: string
      enum:
        - TEAM_GAME
        - TENNIS_MATCH
        - SELECTION_GRID
    MarketLiveDataPolicy:
      type: string
      enum:
        - OPTIONAL_DISPLAY
        - REQUIRED_FOR_IN_PLAY
        - NOT_APPLICABLE
    LivePresentationSnapshot:
      type: object
      additionalProperties: false
      required:
        - provider
        - providerScopeId
        - sport
        - schemaKind
        - isLive
        - isTerminal
        - freshness
        - competitors
        - periods
        - clock
        - summary
        - sourceCursors
        - observedAt
      properties:
        eventId:
          type: string
        bindingHash:
          type: string
        provider:
          type: string
        providerScopeId:
          type: string
        sport:
          type: string
        schemaKind:
          type: string
          enum:
            - TEAM_GAME
            - TENNIS_MATCH
            - GOLF_LEADERBOARD
            - NONE
        providerStatusName:
          type: string
        isLive:
          type: boolean
        isTerminal:
          type: boolean
        freshness:
          type: string
          enum:
            - PRE_EVENT
            - FRESH
            - STALE
            - TERMINAL
            - UNAVAILABLE
        startedAt:
          type: string
          format: date-time
        endedAt:
          type: string
          format: date-time
        competitors:
          type: array
          items:
            $ref: "#/components/schemas/LivePresentationCompetitor"
        periods:
          type: array
          items:
            $ref: "#/components/schemas/LivePresentationPeriod"
        clock:
          $ref: "#/components/schemas/LivePresentationClock"
        summary:
          $ref: "#/components/schemas/LivePresentationSummary"
        sourceCursors:
          type: object
          additionalProperties:
            type: string
        observedAt:
          type: string
          format: date-time
        validUntil:
          type: string
          format: date-time
        revision:
          type: integer
          format: int64
    BookLevel:
      type: object
      required:
        - price
        - qty
      properties:
        price:
          type: number
          description: Decimal price retained for consumer compatibility.
        price_cents:
          type: integer
          minimum: 0
          maximum: 100
          description: Exact integer-cent price used by the canonical trading contract when present.
        qty:
          type: integer
          minimum: 0
    CreateOrderFields:
      type: object
      required:
        - client_order_id
        - market_id
        - market_generation
        - action
        - outcome
        - price_cents
        - quantity
        - time_in_force
      properties:
        client_order_id:
          type: string
          maxLength: 200
          description: Participant-defined order identity, unique within the authenticated account.
        market_id:
          type: string
        market_generation:
          type: integer
          format: int64
          minimum: 1
          description: Exact admission generation fence obtained from the market resource.
        action:
          type: string
          enum:
            - BUY
            - SELL
          description: BUY opens or increases a fully collateralized position in outcome. SELL reduces that
            outcome only and is rejected when unreserved holdings are insufficient; it never
            reverses or nets another outcome.
        outcome:
          type: string
          enum:
            - YES
            - NO
          description: Immutable economic outcome for this order. All public prices and fill notionals use
            this outcome's coordinate.
        price_cents:
          type: integer
          format: int64
          minimum: 0
          maximum: 100
          description: Limit price of outcome, in integer cents. For NO, YM converts once to the complementary
            YES-book price internally; clients must not complement it.
        quantity:
          type: integer
          format: int64
          minimum: 1
        time_in_force:
          type: string
          enum:
            - GTC
            - IOC
            - DAY
          description: GTC is the professional resting primitive; IOC attempts immediate execution; DAY is the
            venue-supported session-scoped alternative.
      example:
        client_order_id: strategy-no-000001
        market_id: example-market
        market_generation: 7
        action: BUY
        outcome: NO
        price_cents: 35
        quantity: 10
        time_in_force: GTC
    CanonicalOrderCommand:
      type: object
      additionalProperties: false
      required:
        - command_id
        - command_type
        - client_request_id
        - admission_status
        - outcome_status
        - created_at
        - updated_at
      properties:
        command_id:
          type: string
          format: uuid
        order_id:
          type: string
          format: uuid
        command_sequence:
          type: integer
          format: int64
          minimum: 1
        command_type:
          type: string
          enum:
            - NEW
            - REPLACE
            - CANCEL
        client_request_id:
          type: string
        client_order_id:
          type: string
        admission_status:
          type: string
          enum:
            - ADMITTED
            - REJECTED
        outcome_status:
          type: string
          enum:
            - PENDING
            - EFFECTIVE
            - REJECTED
            - NOOP
            - CANCELLED_BEFORE_DISPATCH
            - UNKNOWN
        reason_code:
          type: string
        reason_detail:
          type: string
        admitted_at:
          type: string
          format: date-time
        dispatched_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    PrivateFeedCause:
      type: object
      additionalProperties: false
      required:
        - type
      properties:
        type:
          type: string
        command_id:
          type: string
          format: uuid
        client_request_id:
          type: string
        reason_code:
          type: string
    PrivateFeedVenueEvidence:
      type: object
      additionalProperties: false
      required:
        - provider
      description: Participant-safe venue identity. Raw DX replay offsets, session/MPID topology, account
        identity, and the counterparty-side execution identifier are never exposed.
      properties:
        provider:
          type: string
          example: dxmatch
        symbol:
          type: string
        execution_id:
          type: string
          description: The authenticated participant's own DX execution identifier.
        trade_id:
          type: string
          description: Shared DX trade identifier when supplied by the Trading Feed.
        match_id:
          type: string
          description: Shared DX match identifier when supplied by the Trading Feed.
    PrivateFeedFill:
      type: object
      additionalProperties: false
      required:
        - trade_id
        - market_id
        - market_generation
        - price_cents
        - quantity
        - liquidity_role
        - settlement_status
      properties:
        trade_id:
          type: string
        market_id:
          type: string
        market_generation:
          type: integer
          format: int64
        price_cents:
          type: integer
          format: int64
          minimum: 0
          maximum: 100
          description: Participant-relative fill price in the nested order's outcome coordinate; never the
            internal YES-book price for a NO order.
        quantity:
          type: integer
          format: int64
        liquidity_role:
          type: string
          enum:
            - MAKER
            - TAKER
        settlement_status:
          type: string
          enum:
            - POSTED
    CanonicalEventTaxonomy:
      type: object
      additionalProperties: false
      required:
        - category
        - breadcrumbs
      properties:
        category:
          type: string
        sport:
          type: string
        competition:
          type: string
        series:
          type: string
        cycle:
          type: string
        phase:
          type: string
        path_pattern_id:
          type: string
        node_id:
          type: string
        node_key:
          type: string
        path:
          type: string
        breadcrumbs:
          type: array
          items:
            $ref: "#/components/schemas/CanonicalTaxonomyNode"
    MarketFamilyOutcome:
      type: object
      required:
        - id
        - market_id
        - market_generation
        - name
        - probability
        - volume24h
        - change24h
      properties:
        id:
          type: string
        market_id:
          type: string
        market_generation:
          type: integer
          format: int64
          minimum: 0
          description: Current activation generation for this tradable leaf.
        name:
          type: string
        probability:
          type: number
        volume24h:
          type: number
        change24h:
          type: number
        flag:
          type: string
        imageUrl:
          type: string
        entityId:
          type: string
        entitySlug:
          type: string
        entityKind:
          type: string
          enum:
            - team
            - athlete
            - competition
            - venue
        entitySportKey:
          type: string
        shortName:
          type: string
        countryCode:
          type: string
        iconMetadata:
          type: object
          additionalProperties: true
        resolved:
          type: boolean
        result:
          type: string
          enum:
            - win
            - lose
            - void
    CanonicalExternalMapping:
      type: object
      additionalProperties: false
      description: Typed provider identity. Omitted unless `external_mappings` is explicitly requested.
      required:
        - provider
        - namespace
        - role
      properties:
        provider:
          type: string
        namespace:
          type: string
        role:
          type: string
        provider_event_id:
          type: string
        provider_event_slug:
          type: string
        provider_market_id:
          type: string
        provider_outcome_id:
          type: string
        condition_id:
          type: string
        question_id:
          type: string
        selected_token_id:
          type: string
        opposite_token_id:
          type: string
    LivePresentationCompetitor:
      type: object
      additionalProperties: false
      required:
        - key
        - name
      properties:
        key:
          type: string
        name:
          type: string
        score:
          type: number
    LivePresentationPeriod:
      type: object
      additionalProperties: false
      required:
        - key
      properties:
        key:
          type: string
        label:
          type: string
        participant1Score:
          type: number
        participant2Score:
          type: number
        updatedAt:
          type: string
          format: date-time
    LivePresentationClock:
      type: object
      additionalProperties: false
      properties:
        currentPeriod:
          type: string
        currentTime:
          type: string
        remainingTime:
          type: string
        remainingTimeInPeriod:
          type: string
        stopped:
          type: boolean
    LivePresentationSummary:
      type: object
      additionalProperties: false
      properties:
        text:
          type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
x-generated-from: Backend/api/openapi.yaml
x-document-status: controlled-pilot
x-private-trading-feed:
  contract: Private Order & Execution Feed v2
  endpoint: wss://ympredictions.com/v1/trading-feed
  local_endpoint: ws://localhost:8080/v1/trading-feed
  auth:
    type: bearer
    required_scopes:
      - trading-feed:read
    header: Authorization
    participant_identity: derived only from the validated bearer token
  query:
    cursor: optional opaque signed cursor for the last fully applied event
  delivery:
    guarantee: at-least-once
    event_deduplication: event_id
    order_convergence: monotonically increasing order_version
    maximum_uncompressed_frame_bytes: 262144
    compression: disabled
    client_ack_writer: none
  bootstrap:
    - stream.welcome
    - stream.snapshot_started
    - zero or more stream.snapshot_chunk frames containing all nonterminal orders
    - stream.snapshot_completed
    - replay after the snapshot high-water cursor
    - stream.ready
    - live lifecycle events and heartbeats
  messages:
    oneOf:
      - $ref: "#/components/schemas/PrivateFeedLifecycleEvent"
      - $ref: "#/components/schemas/PrivateFeedControlMessage"
