WebSocket Events

Understand Trading API WebSocket payloads, event and sub-markets channel routing, and scope-based classification.

Use this page to interpret Trading API WebSocket payloads under the new event and sub-markets channel model. For the complete connection, subscription-registration, capacity-planning, and Pusher-handshake flow, see Integration with Websockets.

Migration to event and sub-markets channels

Register subscriptions with POST /partner/v4/mm/websocket. This replaces POST /partner/v4/mm/pusher for access to the new channel types.

Market coverageRequired actionDeadline
Player PropsSubscribe to the new Sub-markets channels.July 29, 2026
Main marketsMigrate from the shared main public channel to Event channels.August 12, 2026

Channel routing and scope

ChannelPatternPayloads
Main public channelprivate-broadcast-service=6-device_type=5Existing shared messages. Its market_selections payloads are being phased out.
Event channelprivate-broadcast-service=6-device_type=5-event={event_id}Main-market market_selections for one event.
Sub-markets channelprivate-broadcast-service=6-device_type=5-event={event_id}-subtype={sub_type}Prop market_selections for one event and sub-type.
Private user channelprivate-service=6-device_type=5-user=<your_account_id>Participant-specific order and account updates.

Event and Sub-markets channels both publish market_selections. Use the scope returned in each authorized_channel entry to classify incoming messages, not the channel name. Event-channel scope contains event_id; Sub-markets-channel scope contains event_id and sub_type.

WebSocket event message structure

{
  "timestamp": int64,
  "change_type": string,
  "payload": base64 encoded string,
  "op": string
}

The payload value varies by change_type, as detailed below.

The available op values are:

  • c stands for create
  • u stands for update
  • d stands for delete

Broadcast payloads

The following payload types are published on broadcast channels. During the migration, market_selections moves from the shared main public channel to Event and Sub-markets channels; its payload schema does not change.

The broadcast payload reference includes six event types:

  • tournament
    Sent when a new tournament becomes available, an existing tournament is disabled, or tournament data is updated.
    Payload structure:

    {
      "id": string, // unique tournament identifier
      "info": {
        "banner": string,
        "category": {
          "countryCode": string,
          "id": integer,
          "name": string
        },
        "id": integer, // tournament id
        "image": string,
        "name": string,
        "sport": {
          "id": integer,
          "name": string
        },
        "sequence_number": int
      }
    }
  • market
    Sent when a new market becomes available for an event, a market is removed from an event, or market data is updated.
    Payload structure:

    {
      "id": string, // unique event identifier
      "info": {
        "id": int, // market id
        "sport_event_id": int, // event id, same as outer id
        "name": string,
        "status": string,
        "description": string,
        "sequence_number": int
      }
    }
  • sport_event
    Sent when a new event becomes available in a tournament, an existing event is removed, or event data is updated.
    Payload structure:

    {
      "id": string, // unique event identifier
      "tournament_id": string,
      "info": {
        "competitors": [
          {
            "abbreviation": string,
            "country": string,
            "display_name": string,
            "id": integer, // competitor id
            "name": string,
            "side": string
          }
        ],
        "display_name": string,
        "event_id": integer,
        "name": string,
        "scheduled": string,
        "sport_name": string,
        "status": string,
        "tournament_name": string,
        "type": string,
        "sequence_number": int
      }
    }
  • market_strike
    Sent when a market has a new strike, an existing strike is removed, or strike data is updated.
    Payload structure:

    {
      "id": int, // market_strike id
      "info": {
        "id": int,
        "sport_event_id": int,
        "market_id": int,
        "outcome_id": int,
        "strike": float,
        "strike_id": string,
        "type": string,
        "name": string,
        "status": string,
        "favourite": bool,
        "sequence_number": int
      }
    }
  • market_selections
    Sent for all selections on a strike when selection liquidity changes, such as new resting orders, filled orders, voided orders, or canceled orders. Liquidity is calculated from resting quantity on a strike. Event and Sub-markets channels both publish this event name; classify the message using the channel's scope.
    This event covers resting liquidity only, it does not carry trade prints. For fill details when a match occurs, see trade_execution/matched_bet below — note that one is not published on this channel; see its entry for where to actually bind it.
    Payload structure:

    {
      "sport_event_id": int,
      "market_id": int,
      "info": {
        "id": int,
        "name": string, // market name
        "selections": [
          // Contains two arrays of best selections
          // The current system limits each array to the 10 best selections for this event
          // If no best selection exists, the system returns one placeholder selection
          [
            {
              "outcome_id": int,
              "name": string,
              "competitor_id": int,
              "strike": float,
              "strike_id": string,
              "price": float,
              "display_price": string,
              "display_strike": string,
              "display_name": string,
              "value": float,
              "quantity": float,
              "updated_at": int
            }
          ],
          [
            {
              "outcome_id": int,
              "name": string,
              "competitor_id": int,
              "strike": float,
              "strike_id": string,
              "price": float,
              "display_price": string,
              "display_strike": string,
              "display_name": string,
              "value": float,
              "quantity": float,
              "updated_at": int
            }
          ]
        ],
        "type": string,
        "strike": float,
        "sequence_number": int
      }
    }
  • trade_execution (legacy name: matched_bet)
    Sent when a successful fill occurs. This event broadcasts the filled price details to all listeners — anonymized, with no order-ownership information.
    This is not published on the Event or Sub-markets channel that carries market_selections. It's bound on the channel you get from a {"type": "tournament", "ids": [...]} subscription — the same one that also carries tournament/general — under the binding name tournament_{tournament_id} (or, if you registered for CFTC-vocabulary responses, also v2.tournament_{tournament_id}, which carries this trade_execution payload; the plain tournament_{tournament_id} name carries the legacy matched_bet payload instead, with wager-vocabulary field names). Bind whichever name(s) actually appear in your registration response's binding_events — that's authoritative over anything hardcoded here.
    Payload example (CFTC vocabulary, trade_execution):

    {
      "info": {
        "strike": 0,
        "strike_id": "cffa7ddc4fd50acbe51684e7addabe00",
        "market_id": 219,
        "fill_price": 124,
        "filled_quantity": 45.3,
        "price": 124,
        "origin_market_strike": 0,
        "outcome_id": 4,
        "sequence_number": 1709130007835319000,
        "sport_event_id": 44285780,
        "aggressive": true
      }
    }

    The legacy matched_bet payload carries the same shape with wager-vocabulary field names (line/odds/matched_odds/matched_stake/line_id/origin_market_line in place of strike/price/fill_price/filled_quantity/strike_id/origin_market_strike).

Private user channel

Messages sent through this channel are available only to your participant session.

The private channel publishes two event types:

  • orders
    Sent when your order status changes. You receive updates when an order is activated, canceled, or filled, including updated order metadata. This is how you learn about fills on your own orders specifically — trade_execution/matched_bet on the broadcast channels is the anonymized public trade tape and doesn't identify whose order filled.
    Payload structure:

    {
      "info": {
        "id": string,
        "user_id": string,
        "market_id": int,
        "sport_event_id": int,
        "outcome_id": int,
        "price": float,
        "strike": float,
        "quantity": float,
        "profit": float,
        "filled_quantity": float,
        "fill_price": float,
        "total_filled_quantity": float,
        "open_quantity": float,
        "matching_status": string,
        "winning_status": string,
        "status": string,
        "external_id": string,
        "strike_id": string,
        "update_type": string,
        "matching_id": int,
        "origin_market_strike": float,
        "aggressive": bool,
        "sequence_number": int
      }
    }
  • health_check
    Sent to all WebSocket sessions every 5 seconds to help you monitor connection health.
    Payload example:

    {
      "event": "health_check",
      "data": {
        "change_type": "private_system_signal",
        "op": "u",
        "payload": "e30=",
        "timestamp": 1717689526365275600
      }
    }

Did this page help you?