> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sx.bet/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Book Updates

> Subscribe to real-time changes in a market's order book

Subscribe to changes in a particular order book. You will receive updates when orders are filled, cancelled, or posted. Note that for performance reasons, updates are delayed by at most 100ms.

There are two channels for order book data. Each publish is broadcast to both:

| Channel                            | Subscribe when you want to...       |
| ---------------------------------- | ----------------------------------- |
| `order_book:market_{marketHash}`   | Track a specific market             |
| `order_book:event_{sportXeventId}` | Track all markets for a given event |

<Info>
  The channel no longer includes a `baseToken` parameter. The payload's `marketHash` field can be used to identify the token if needed.
</Info>

***

## By market

**CHANNEL NAME FORMAT**

`order_book:market_{marketHash}`

| Name       | Type   | Description                |
| ---------- | ------ | -------------------------- |
| marketHash | string | The market to subscribe to |

<CodeGroup>
  ```javascript JavaScript theme={null}
  // To subscribe
  const marketHash = "0x04b9af76dfb92e71500975db77b1de0bb32a0b2413f1b3facbb25278987519a7";
  const sub = client.newSubscription(`order_book:market_${marketHash}`, { positioned: true, recoverable: true });

  sub.on("publication", (ctx) => {
    const data = ctx.data;
    // message handler logic
  });

  sub.subscribe();
  ```

  ```python Python theme={null}
  import asyncio
  from centrifuge import Client, PublicationContext, SubscriptionEventHandler

  async def on_publication(ctx: PublicationContext) -> None:
      print(ctx.data)

  async def main():
      market_hash = "0x04b9af76dfb92e71500975db77b1de0bb32a0b2413f1b3facbb25278987519a7"
      client = Client(
          "wss://realtime.sx.bet/connection/websocket",
          token="YOUR_TOKEN",  # from /user/realtime-token/api-key
      )
      await client.connect()
      handler = SubscriptionEventHandler(on_publication=on_publication)
      sub = client.new_subscription(f"order_book:market_{market_hash}", handler)
      await sub.subscribe()
      await asyncio.Future()  # keep running

  asyncio.run(main())
  ```
</CodeGroup>

***

## By event

**CHANNEL NAME FORMAT**

`order_book:event_{sportXeventId}`

| Name          | Type   | Description                                                                   |
| ------------- | ------ | ----------------------------------------------------------------------------- |
| sportXeventId | string | The event to subscribe to. Receives updates for all markets under this event. |

<CodeGroup>
  ```javascript JavaScript theme={null}
  // To subscribe
  const eventId = "L13772588";
  const sub = client.newSubscription(`order_book:event_${eventId}`, { positioned: true, recoverable: true });

  sub.on("publication", (ctx) => {
    const data = ctx.data;
    // message handler logic
  });

  sub.subscribe();
  ```

  ```python Python theme={null}
  import asyncio
  from centrifuge import Client, PublicationContext, SubscriptionEventHandler

  async def on_publication(ctx: PublicationContext) -> None:
      print(ctx.data)

  async def main():
      event_id = "L13772588"
      client = Client(
          "wss://realtime.sx.bet/connection/websocket",
          token="YOUR_TOKEN",  # from /user/realtime-token/api-key
      )
      await client.connect()
      handler = SubscriptionEventHandler(on_publication=on_publication)
      sub = client.new_subscription(f"order_book:event_{event_id}", handler)
      await sub.subscribe()
      await asyncio.Future()  # keep running

  asyncio.run(main())
  ```
</CodeGroup>

***

## Message payload

Both channels share the same payload format. The message is an array of order objects with the fields below — the same fields as in [the orders section](/api-reference/get-orders), with additional `status` and `updateTime` fields.

| Name                     | Type    | Description                                                                                                                                                                                                                          |
| ------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| orderHash                | string  | A unique identifier for this order                                                                                                                                                                                                   |
| marketHash               | string  | The market for this order                                                                                                                                                                                                            |
| status                   | string  | `"ACTIVE"` if still valid, `"INACTIVE"` if cancelled, `"FILLED"` if completely filled                                                                                                                                                |
| fillAmount               | string  | How much this order has been filled in Ethereum units. See [unit conversion](/api-reference/unit-conversion).                                                                                                                        |
| pendingFillAmount        | string  | Amount pending fill in Ethereum units. See [unit conversion](/api-reference/unit-conversion).                                                                                                                                        |
| maker                    | string  | The market maker for this order                                                                                                                                                                                                      |
| totalBetSize             | string  | Total size of this order in Ethereum units. See [unit conversion](/api-reference/unit-conversion).                                                                                                                                   |
| percentageOdds           | string  | The odds the `maker` receives in the sportx protocol format. To convert to implied odds divide by 10^20. To get taker implied odds: `takerOdds = 1 - percentageOdds / 10^20`. See [unit conversion](/api-reference/unit-conversion). |
| expiry                   | number  | Deprecated. Always `2209006800`.                                                                                                                                                                                                     |
| apiExpiry                | number  | The time in unix seconds after which this order is no longer valid                                                                                                                                                                   |
| salt                     | string  | A random number to differentiate identical orders                                                                                                                                                                                    |
| isMakerBettingOutcomeOne | boolean | `true` if the maker is betting outcome one                                                                                                                                                                                           |
| signature                | string  | Signature of the maker on this order                                                                                                                                                                                                 |
| updateTime               | string  | Server-side clock time for the last modification of this order                                                                                                                                                                       |
| sportXeventId            | string  | The event related to this order                                                                                                                                                                                                      |

Messages are sent in batches as an array. If you receive two updates for the same `orderHash`, order them by `updateTime` after converting to a BigInt.

```json theme={null}
[
  {
    "orderHash": "0x7bd76648f589f3e272d48294d8881fe68aae7704f7b2ef0a50bf612be44271",
    "marketHash": "0x04b9af76dfb92e71500975db77b1de0bb32a0b2413f1b3facbb25278987519a7",
    "status": "INACTIVE",
    "fillAmount": "2000000000",
    "pendingFillAmount": "1000000000",
    "maker": "0x9883D5e7dC023A441A81Ef95af406C69926a0AB6",
    "totalBetSize": "500000000",
    "percentageOdds": "750000000000000000000",
    "expiry": 1747500000000,
    "apiExpiry": 1747500000000,
    "salt": "12345678901234567890",
    "isMakerBettingOutcomeOne": false,
    "signature": "0xbf099ab02255d5e2a9e063dc43a7afe96e65f5e8fc2ed3d2ba60b0a3fcadb3441bf32271293e85b7a795c9d86a2384035a0da3285113e746547e236bc58885e01",
    "updateTime": 1747490000000,
    "sportXeventId": "L13772588"
  }
]
```
