Get order book changes
Every order book change in a time window, from a full starting book.
Hosted by Synpath. Authentication: Authorization: Bearer <Synpath API key>. Venue coverage: Kalshi.
Returns the window as segments. A data segment carries the full book at its start (initial_book) followed by every change in recorder order: a delta is one price level's exact quantity change on one side; a snapshot replaces the whole book. An absent segment marks an interval with no coverage. Apply the changes in order to reconstruct the book at any point in the window.
Windows are at most one hour. A response is always complete: when the changes exceed limit the request is refused with 413 rather than truncated; use a smaller window or a higher limit. next_cursor is always null.
Request body
| Name | Type | Description |
|---|---|---|
market_id | string | Synpath market id, venue:native. |
start_ms | integer | Window start, inclusive, Unix milliseconds. |
end_ms | integer | Window end, exclusive. At most one hour after start_ms. |
side | stringdefault yes | yes or no. |
limit | integerdefault 1000 | Maximum changes to return, up to 10000. Exceeding it answers 413. |
Response fields
| Name | Type | Description |
|---|---|---|
metadata.dataset_version | string | Processed dataset the answer was read from. Pin it when comparing answers. |
metadata.time_basis | string | recorder_receive: every timestamp below is the time the recorder received the event. |
segments[].kind | string | data or absent. |
segments[].start_ms, end_ms | integer | The interval the segment covers. |
segments[].initial_book | object | Full book at start_ms of a data segment; same shape as Get order book snapshot's book. |
segments[].changes[].kind | string | delta or snapshot. |
segments[].changes[].observed_at_ms | integer | Recorder receive time of the change. |
segments[].changes[].book_side | string | bid or ask, for a delta. |
segments[].changes[].price_exact | string | Price level of a delta, as an exact decimal string. |
segments[].changes[].quantity_delta_exact | string | Change in size at that level, exact decimal; negative when liquidity was removed. |
segments[].changes[].book | object | The new full book, for a snapshot. |
segments[].reason | string | Why an absent segment has no coverage. |
Response
200 with the segments covering the window. 413 when the changes exceed limit.
import synpath
changes = synpath.fetch_order_book_range("kalshi:KXQUANTUM-30", 1789509479000, 1789509599000, limit=5000)
for segment in changes.segments:
print(segment.kind, segment.start_ms, segment.end_ms, len(segment.changes), segment.reason){
"metadata": {
"dataset_version": "processed-v1-623446e80ca97c2b",
"time_basis": "recorder_receive",
"processed_through_ms": 1789725040929
},
"market_id": "kalshi:KXQUANTUM-30",
"start_ms": 1789509479000,
"end_ms": 1789509599000,
"segments": [
{
"kind": "data",
"start_ms": 1789509479000,
"end_ms": 1789509599000,
"initial_book": {
"market_id": "kalshi:KXQUANTUM-30",
"side": "yes",
"venue": "kalshi",
"bids": [
{
"price": 0.331,
"size": 66
},
{
"price": 0.33,
"size": 500
}
],
"asks": [
{
"price": 0.36,
"size": 10
},
{
"price": 0.37,
"size": 50
}
],
"timestamp": 1789509152200,
"datetime": "2026-09-15T21:52:32.200Z",
"book_model": "shared_complement",
"derived": true,
"depth_scope": "top_n",
"info": {
"...": "the venue's payload"
},
"as_of_ms": 1789509479000,
"venue_timestamp_ms": null,
"best_bid": {
"price": 0.331,
"size": 66
},
"best_ask": {
"price": 0.36,
"size": 10
}
},
"changes": [
{
"kind": "delta",
"observed_at_ms": 1789509521440,
"venue_timestamp_ms": null,
"book_side": "ask",
"price_exact": "0.36",
"quantity_delta_exact": "-10",
"book": null
}
],
"reason": null
}
],
"next_cursor": null
}
