Oddpool WebSocket Feeds

Single-connection WebSocket streaming real-time, normalized cross-venue prediction market data (dist, book, trade, and snapshot channels) for macro economic events and crypto (BTC/ETH) markets enriched with Binance spot/futures reference data. Authenticated with an in-band auth message.

AsyncAPI Specification

oddpool-feeds-asyncapi.yml Raw ↑
generated: '2026-07-20'
method: generated
source: https://docs.oddpool.com/websocket/overview.md
x-provenance: >-
  Generated by the API Evangelist enrichment pipeline from Oddpool's published
  WebSocket documentation (overview, message reference, limits). Oddpool does not
  publish an AsyncAPI document; message shapes below are faithful to the
  documented payloads. Not an authoritative provider artifact.
asyncapi: 3.0.0
info:
  title: Oddpool WebSocket Feeds
  version: 1.0.0
  description: >-
    Single-connection WebSocket streaming real-time, normalized cross-venue
    prediction market data from Kalshi and Polymarket. Data is addressed by what
    (event_key / outcome) not where (venue). Four channel types: dist and
    snapshot are event-level; book and trade are per-outcome. Crypto events are
    enriched with Binance spot/futures reference data.
servers:
  production:
    host: feeds.oddpool.com
    pathname: /ws
    protocol: wss
    description: Production WebSocket endpoint (wss://feeds.oddpool.com/ws).
channels:
  ws:
    address: /ws
    description: The single multiplexed WebSocket connection; messages are addressed by channel string.
    messages:
      auth:
        $ref: '#/components/messages/AuthRequest'
      authResponse:
        $ref: '#/components/messages/AuthResponse'
      subscribe:
        $ref: '#/components/messages/SubscribeRequest'
      subscribed:
        $ref: '#/components/messages/SubscribedResponse'
      dist:
        $ref: '#/components/messages/DistMessage'
      book:
        $ref: '#/components/messages/BookMessage'
      trade:
        $ref: '#/components/messages/TradeMessage'
      snapshot:
        $ref: '#/components/messages/SnapshotMessage'
operations:
  authenticate:
    action: send
    channel:
      $ref: '#/channels/ws'
    messages:
    - $ref: '#/channels/ws/messages/auth'
  subscribe:
    action: send
    channel:
      $ref: '#/channels/ws'
    messages:
    - $ref: '#/channels/ws/messages/subscribe'
  receiveDist:
    action: receive
    channel:
      $ref: '#/channels/ws'
    messages:
    - $ref: '#/channels/ws/messages/dist'
    - $ref: '#/channels/ws/messages/book'
    - $ref: '#/channels/ws/messages/trade'
    - $ref: '#/channels/ws/messages/snapshot'
components:
  messages:
    AuthRequest:
      name: auth
      summary: Authenticate the connection with an API key.
      payload:
        type: object
        properties:
          action:
            type: string
            const: auth
          api_key:
            type: string
            description: The oddpool_ API key.
    AuthResponse:
      name: authResponse
      summary: Server confirmation with resolved tier and limits.
      payload:
        type: object
        properties:
          type: {type: string, const: auth}
          status: {type: string, example: ok}
          user_id: {type: integer}
          tier: {type: string, example: pro}
          limits:
            type: object
            properties:
              max_events: {type: integer, description: 0 means unlimited (Premium+).}
              max_connections: {type: integer}
              channels:
                type: array
                items: {type: string, enum: [dist, book, trade, snapshot]}
    SubscribeRequest:
      name: subscribe
      summary: Subscribe or unsubscribe to channels by event.
      payload:
        type: object
        properties:
          action: {type: string, enum: [subscribe, unsubscribe]}
          channels:
            type: array
            items:
              type: string
              description: '{type}:{event_key} or {type}:{event_key}:{outcome}'
    SubscribedResponse:
      name: subscribed
      summary: Confirms subscribed channels; rejected[] present only on rejections.
      payload:
        type: object
        properties:
          type: {type: string, const: subscribed}
          channels: {type: array, items: {type: string}}
          rejected:
            type: array
            items:
              type: object
              properties:
                channel: {type: string}
                reason:
                  type: string
                  enum: [unknown_event_key, unknown_channel_type, missing_event_key]
                event_key: {type: string}
    DistMessage:
      name: dist
      summary: Cross-venue probability distribution for all outcomes of an event.
      payload:
        type: object
        properties:
          channel: {type: string, example: 'dist:fomc-2026-04-29'}
          data:
            type: object
            properties:
              event_key: {type: string}
              seq: {type: integer}
              published_ts: {type: integer}
              outcomes:
                type: array
                items:
                  type: object
                  properties:
                    outcome: {type: string}
                    label: {type: string}
                    kalshi_prob: {type: number, nullable: true}
                    poly_prob: {type: number, nullable: true}
                    prob: {type: number}
                    kalshi_depth_usd: {type: number}
                    poly_depth_usd: {type: number}
              total_kalshi_depth_usd: {type: number}
              total_poly_depth_usd: {type: number}
    BookMessage:
      name: book
      summary: Normalized orderbook update for one outcome on one venue.
      payload:
        type: object
        properties:
          channel: {type: string, example: 'book:fomc-2026-04-29:hold'}
          data:
            type: object
            properties:
              event_key: {type: string}
              outcome: {type: string}
              venue: {type: string, enum: [kalshi, polymarket]}
              token: {type: string}
              seq: {type: integer}
              update_type: {type: string, enum: [delta, snapshot]}
              levels:
                type: array
                items:
                  type: object
                  properties:
                    side: {type: string, enum: [bid, ask]}
                    price: {type: string}
                    size: {type: number}
              best_bid: {type: string}
              best_ask: {type: string}
              mid: {type: string}
              spread: {type: string}
    TradeMessage:
      name: trade
      summary: Trade executions for one outcome.
      payload:
        type: object
        properties:
          channel: {type: string, example: 'trade:fomc-2026-04-29:hold'}
          data:
            type: object
            description: Trade execution record for the outcome.
    SnapshotMessage:
      name: snapshot
      summary: Full state reset every 60s for all outcomes of an event.
      payload:
        type: object
        properties:
          channel: {type: string, example: 'snapshot:fomc-2026-04-29'}
          data:
            type: object
            properties:
              distribution:
                type: array
                description: Per-outcome list with full orderbook state per outcome.
                items: {type: object}