@0xmonaco/types 1.0.65 → 1.0.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,9 +64,11 @@ export type WebSocketErrorCode =
64
64
  */
65
65
  | "SNAPSHOT_UNAVAILABLE"
66
66
  /**
67
- * The per-connection inbound message-rate cap was exceeded; the connection
68
- * is closed (1008) after this frame. Batch subscriptions and back off
69
- * before reconnecting — a hot re-subscribe loop trips the cap again.
67
+ * A per-connection inbound cap was exceeded: the message rate, or the byte
68
+ * budget that refuses a burst of very large frames. The connection is
69
+ * closed (1008) after this frame. Batch subscriptions, keep frames small,
70
+ * and back off before reconnecting — a hot re-subscribe loop trips the cap
71
+ * again.
70
72
  */
71
73
  | "MESSAGE_RATE_LIMIT";
72
74
  /**
@@ -82,9 +84,39 @@ export interface WebSocketErrorInfo {
82
84
  code: WebSocketErrorCode | (string & {});
83
85
  /** Human-readable description; for logging and display, never for branching. */
84
86
  message: string;
87
+ /**
88
+ * The channel a per-channel failure concerns, echoed exactly as this client
89
+ * sent it (an unparseable string included). Present on
90
+ * `INVALID_SUBSCRIPTION`, `AUTH_REQUIRED`, `SUBSCRIPTION_LIMIT` and
91
+ * `SNAPSHOT_UNAVAILABLE`; absent on connection-wide failures.
92
+ *
93
+ * `Subscribed` / `Unsubscribed` acks list only the channels a request
94
+ * changed, so a rejected channel is missing from the ack and reported by
95
+ * its own `Error` frame instead — this is how to pair the two, e.g. to
96
+ * resync only the channel whose snapshot was unavailable.
97
+ */
98
+ channel?: string;
85
99
  }
86
100
  /** Handler invoked for every `Error` frame the server sends. */
87
101
  export type ErrorHandler = (info: WebSocketErrorInfo) => void;
102
+ /**
103
+ * Why the connection stopped reconnecting and needs fresh credentials.
104
+ * Delivered by {@link MonacoWebSocketConfig.onReauthenticationRequired}.
105
+ */
106
+ export interface WebSocketReauthenticationInfo {
107
+ /**
108
+ * The `Error` frame code that ended the connection: `SESSION_INVALID` (the
109
+ * session was revoked or expired after the handshake) or `AUTH_FAILED` (the
110
+ * `Authenticate` handshake itself was rejected).
111
+ */
112
+ code: "SESSION_INVALID" | "AUTH_FAILED";
113
+ /** Human-readable description from the `Error` frame; for logging and display, never for branching. */
114
+ message: string;
115
+ /** WebSocket close code of the connection that was lost (1008 for `SESSION_INVALID`). */
116
+ closeCode: number;
117
+ }
118
+ /** Handler invoked when the connection lost its authentication terminally. */
119
+ export type ReauthenticationRequiredHandler = (info: WebSocketReauthenticationInfo) => void;
88
120
  /**
89
121
  * Reconnect/resync knobs and callbacks for the Monaco WebSocket client.
90
122
  *
@@ -121,23 +153,47 @@ export interface MonacoWebSocketConfig {
121
153
  /**
122
154
  * Called for every `Error` frame the server sends on this connection.
123
155
  *
124
- * `Error` frames are connection-scoped, not channel-scoped, so they reach no
125
- * subscription handler — without this callback a failed subscribe, an
126
- * invalidated session, or an unreadable subscribe-time snapshot is invisible
127
- * to the app. Branch on `code`:
156
+ * `Error` frames match no subscription, so they reach no channel handler —
157
+ * without this callback a failed subscribe, an invalidated session, or an
158
+ * unreadable subscribe-time snapshot is invisible to the app. A failure
159
+ * caused by one requested channel additionally carries
160
+ * {@link WebSocketErrorInfo.channel}, the channel string this client sent;
161
+ * a connection-wide failure carries none. Branch on `code`:
128
162
  *
129
- * - `SNAPSHOT_UNAVAILABLE` — live diffs flow but the baseline is missing;
130
- * refetch it. The subscription itself is fine.
131
- * - `SESSION_INVALID` — re-authenticate rather than reconnect into the same
132
- * rejection.
133
- * - `AUTH_REQUIRED` — a rejected SUBSCRIBE, not an invalidated session: the
134
- * channel was never registered, and this client still holds your handler,
135
- * so it treats the channel as subscribed and sends no new `Subscribe`.
136
- * Re-authenticating alone leaves it dead. Release the last handler for the
137
- * channel and subscribe again after authenticating (0XM-2644 tracks doing
138
- * this automatically).
163
+ * - `SNAPSHOT_UNAVAILABLE` — live diffs flow but that channel's baseline is
164
+ * missing; refetch it for `channel` alone. The subscription itself is fine.
165
+ * - `SESSION_INVALID` — the session was revoked or expired; the connection
166
+ * closes and {@link onReauthenticationRequired} follows. No `channel`.
167
+ * - `AUTH_REQUIRED` — a rejected SUBSCRIBE of `channel`, not an invalidated
168
+ * session: it was never registered, and this client still holds your
169
+ * handler, so it treats the channel as subscribed and sends no new
170
+ * `Subscribe`. Re-authenticating alone leaves it dead. Release the last
171
+ * handler for that channel and subscribe again after authenticating
172
+ * (0XM-2644 tracks doing this automatically).
139
173
  */
140
174
  onError?: ErrorHandler;
175
+ /**
176
+ * Called once when the connection lost its authentication terminally: the
177
+ * server invalidated the session (`SESSION_INVALID`, then a 1008 close) or
178
+ * rejected this connection's `Authenticate` handshake (`AUTH_FAILED`).
179
+ *
180
+ * Reconnecting with the same credentials would only be rejected again, so
181
+ * the client does not reconnect automatically after either. It forgets the
182
+ * rejected session keypair, keeps your subscription handlers, and reports
183
+ * `"disconnected"`. Obtain a fresh session and pass it to
184
+ * `setSessionKeypair` (the SDK's `login` does this): the client reconnects,
185
+ * authenticates with it, resubscribes every held channel, and fires
186
+ * {@link onResync} so you can reconcile what was missed — also when
187
+ * {@link autoReconnect} is off. A session you already replaced before the
188
+ * close (e.g. from {@link onError}) is kept, and the client reconnects with
189
+ * it instead of calling this. Supply the fresh session rather than calling
190
+ * `connect()` first: a session-less socket re-sends user-specific channels
191
+ * unauthenticated, and the server rejects them with `AUTH_REQUIRED`.
192
+ *
193
+ * Every other abnormal close — including a 1008 for exceeding the message
194
+ * rate cap and a 1013 slow-client shed — keeps the backoff reconnect.
195
+ */
196
+ onReauthenticationRequired?: ReauthenticationRequiredHandler;
141
197
  }
142
198
  /**
143
199
  * Raw event message interface
@@ -7,8 +7,13 @@ import type { ConditionalOrderConditionType, ConditionalOrderState, ConditionalO
7
7
  * wire field is a free-form server string rather than a closed enum, so this
8
8
  * alias is documentation and a narrowing aid only. Match on it with a default
9
9
  * branch; see `ConditionalOrderEventData.reason`.
10
+ *
11
+ * A `TRAILING_STOP` row adds two: `armed` when tracking begins (its
12
+ * `activationPrice` was reached, or immediately when none was set) and
13
+ * `ratcheted` on every move of its trigger, carrying the new `triggerPrice`
14
+ * and the `watermarkPrice` it was derived from (0XM-2827).
10
15
  */
11
- export type ConditionalOrderEventReason = "created" | "activated" | "cancelled" | "parent_cancelled" | "triggered" | "failed" | "oco_cancelled";
16
+ export type ConditionalOrderEventReason = "created" | "activated" | "cancelled" | "parent_cancelled" | "triggered" | "failed" | "oco_cancelled" | "armed" | "ratcheted";
12
17
  /**
13
18
  * A conditional (TP/SL) order's current state.
14
19
  *
@@ -82,6 +87,29 @@ export interface ConditionalOrderEventData {
82
87
  cancelledAt?: string;
83
88
  expiresAt?: string;
84
89
  failureReason?: string;
90
+ /**
91
+ * `TRAILING_STOP` only: retracement in basis points behind the watermark.
92
+ * Absent (`null` on the wire) on TP/SL rows. Wire: `trail_bps`.
93
+ */
94
+ trailBps?: number;
95
+ /**
96
+ * `TRAILING_STOP` only: the mark level that starts tracking. Absent when the
97
+ * stop armed immediately. Wire: `activation_price`.
98
+ */
99
+ activationPrice?: string;
100
+ /**
101
+ * `TRAILING_STOP` only: best mark (highest for a long, lowest for a short)
102
+ * observed since arming — `triggerPrice` is derived from it and only ever
103
+ * moves in the position's favour. A `ratcheted` frame carries both. Absent
104
+ * until the first mark is observed after arming. Wire: `watermark_price`.
105
+ */
106
+ watermarkPrice?: string;
107
+ /**
108
+ * `TRAILING_STOP` only: when tracking began (ISO 8601). Absent while the
109
+ * stop is still waiting for `activationPrice` — `state` stays `ACTIVE` in
110
+ * both phases. Wire: `trail_armed_at`.
111
+ */
112
+ trailArmedAt?: string;
85
113
  /**
86
114
  * What produced this update. Free-form on the wire — the server field is a
87
115
  * plain string, not an enum — but a live update's canonical values are the
@@ -89,6 +117,13 @@ export interface ConditionalOrderEventData {
89
117
  * snapshot builds the same shape with `"snapshot"` instead.
90
118
  */
91
119
  reason: string;
120
+ /**
121
+ * When the conditional order was created (ISO 8601): the same string REST
122
+ * returns as `createdAt` for this id, on live updates and snapshot rows
123
+ * alike. Always present from current servers; optional so a frame from an
124
+ * older deployment during a rolling release still parses. Wire: `created_at`.
125
+ */
126
+ createdAt?: string;
92
127
  updatedAt: string;
93
128
  /**
94
129
  * Opaque, compare-only revision counter for this conditional order's state —
@@ -2972,13 +2972,18 @@ export interface components {
2972
2972
  updatedAt?: string | null;
2973
2973
  };
2974
2974
  AttachPositionTpSlRequest: {
2975
+ /**
2976
+ * @description Trailing stop (0XM-2827). May be attached alone or alongside take_profit /
2977
+ * stop_loss; it never takes part in oco and coexists with fixed legs.
2978
+ */
2979
+ trailingStop?: components["schemas"]["TrailingStopLeg"] | null;
2980
+ takeProfit?: components["schemas"]["TpSlLeg"];
2981
+ stopLoss?: components["schemas"]["TpSlLeg"];
2975
2982
  /**
2976
2983
  * @description One-cancels-the-other. Defaults to false. When true, both take_profit and
2977
2984
  * stop_loss are required and the sibling is cancelled after either triggers.
2978
2985
  */
2979
2986
  oco?: boolean | null;
2980
- takeProfit?: components["schemas"]["TpSlLeg"];
2981
- stopLoss?: components["schemas"]["TpSlLeg"];
2982
2987
  };
2983
2988
  AttachPositionTpSlResponse: {
2984
2989
  positionId?: string | null;
@@ -2986,6 +2991,7 @@ export interface components {
2986
2991
  stopLossOrderId?: string | null;
2987
2992
  status?: string | null;
2988
2993
  message?: string | null;
2994
+ trailingStopOrderId?: string | null;
2989
2995
  };
2990
2996
  BatchCancelAllResponse: {
2991
2997
  /**
@@ -3191,7 +3197,7 @@ export interface components {
3191
3197
  */
3192
3198
  riskBucketId?: string | null;
3193
3199
  /**
3194
- * @description Decimal collateral to allocate into a new isolated risk bucket. When provided, the API creates the bucket ID and matching-engine persists the bucket through the durable log.
3200
+ * @description Decimal collateral allocated as an order budget in a new isolated risk bucket. Fills commit their required margin and paid-fee funding to position backing; unfilled or unused order funds do not protect the position from liquidation. Use position margin adjustment to add liquidation protection. The API creates the bucket ID and the matching engine persists it through the durable log.
3195
3201
  * @example 1000
3196
3202
  */
3197
3203
  riskBucketCollateral?: string | null;
@@ -3691,6 +3697,17 @@ export interface components {
3691
3697
  version?: number | null;
3692
3698
  /** @description Present only when state is TRIGGERED: the execution outcome of the order this conditional fired into (triggeredOrderId) — status, filled quantity, volume-weighted average fill price, taker fees and fill time — read from that order at request time. Trigger price and fill price are different numbers: the trigger fires on the mark price and the leg then trades against the book, so a MARKET leg fills at least the half-spread plus its own impact away from triggerPrice, and a LIMIT leg may still be resting (SUBMITTED / PARTIALLY_FILLED) or have been cut by the protective band (CANCELLED with a terminalReason). Absent while waiting on the trigger, on the conditional_orders WebSocket frames, and in the rare case the triggered order cannot be read. */
3693
3699
  triggeredOrder?: components["schemas"]["TriggeredOrderSummary"] | null;
3700
+ /**
3701
+ * Format: int32
3702
+ * @description TRAILING_STOP only: retracement in basis points behind the watermark.
3703
+ */
3704
+ trailBps?: number | null;
3705
+ /** @description TRAILING_STOP only: mark level that starts tracking. Absent when the stop armed immediately. */
3706
+ activationPrice?: string | null;
3707
+ /** @description TRAILING_STOP only: best mark (highest for a long, lowest for a short) observed since arming. triggerPrice is derived from it and only ever moves in the position's favour. Absent until the first mark is observed after arming. */
3708
+ watermarkPrice?: string | null;
3709
+ /** @description TRAILING_STOP only: when tracking began. Absent while the stop is still waiting for activationPrice (state stays ACTIVE in both phases). */
3710
+ trailArmedAt?: string | null;
3694
3711
  };
3695
3712
  CreateDelegatedSessionRequest: {
3696
3713
  /**
@@ -3814,7 +3831,7 @@ export interface components {
3814
3831
  */
3815
3832
  riskBucketId?: string | null;
3816
3833
  /**
3817
- * @description Decimal collateral to allocate into a new isolated risk bucket. When provided, the API creates the bucket ID and matching-engine persists the bucket through the durable log.
3834
+ * @description Decimal collateral allocated as an order budget in a new isolated risk bucket. Fills commit their required margin and paid-fee funding to position backing; unfilled or unused order funds do not protect the position from liquidation. Use position margin adjustment to add liquidation protection. The API creates the bucket ID and the matching engine persists it through the durable log.
3818
3835
  * @example 1000
3819
3836
  */
3820
3837
  riskBucketCollateral?: string | null;
@@ -3866,6 +3883,8 @@ export interface components {
3866
3883
  * @enum {string|null}
3867
3884
  */
3868
3885
  selfTradePreventionMode?: "CANCEL_MAKER" | "CANCEL_TAKER" | "CANCEL_BOTH" | "SKIP" | null;
3886
+ /** @description Trailing stop attached to this entry order (margin only). Arms only when the order fully fills; cancelled with the order otherwise. One per position. */
3887
+ trailingStop?: components["schemas"]["ParentTrailingStopLeg"] | null;
3869
3888
  };
3870
3889
  CreateOrderResponse: {
3871
3890
  /**
@@ -3912,6 +3931,11 @@ export interface components {
3912
3931
  * @description Delegated agent UUID when submitted through a delegated session
3913
3932
  */
3914
3933
  delegationId?: string | null;
3934
+ /**
3935
+ * Format: uuid
3936
+ * @description Conditional order id of the trailing stop attached to this entry order, when one was requested
3937
+ */
3938
+ trailingStopOrderId?: string | null;
3915
3939
  };
3916
3940
  CreateTwapOrderRequest: {
3917
3941
  /**
@@ -5453,22 +5477,16 @@ export interface components {
5453
5477
  unrealizedPnl?: string | null;
5454
5478
  realizedPnl?: string | null;
5455
5479
  /**
5456
- * @description Open ISOLATED rows: the position's current backing — its risk bucket's
5457
- * allocated collateral adjusted by settled realized PnL and funding paid,
5458
- * net of collateral reserved for the bucket's open orders, clamped at zero
5459
- * (0XM-2558). Partial closes and partial liquidations shrink the posted
5460
- * margin pro-rata while the realized loss stays in the bucket, so this,
5461
- * not the posted margin, is the unrealized-return denominator. Not a hard
5462
- * -100% bound: the liquidation trigger and liquidation_price measure the
5463
- * bucket's whole equity, order reserves included, so with a resting order
5464
- * the return can pass -100% by that order's earmark before liquidation
5465
- * lands; a mark can gap past the backing before the asynchronous
5466
- * liquidation; a fully drained bucket serves "0". Served from the live risk
5467
- * engine; when only persisted state is reachable the value is gross of
5468
- * order reserves. Open CROSS rows fall back to the position's posted
5469
- * margin. Terminal rows: total initial margin allocated across the
5470
- * position's reducing executions when available — the margin basis for
5471
- * lifetime realized return.
5480
+ * @description Open ISOLATED rows: principal committed to the filled position, adjusted
5481
+ * by settled realized PnL, fees and funding, clamped at zero. Collateral
5482
+ * allocated to unfilled orders is excluded. This is the unrealized-return
5483
+ * denominator and the same backing used by isolated liquidation. Placing,
5484
+ * cancelling or resizing an unfilled order does not add position backing.
5485
+ * A price gap can pass the backing before asynchronous liquidation occurs.
5486
+ * Live and persisted reads use the same position-principal basis.
5487
+ * Open CROSS rows: the position's posted margin. Terminal rows: total
5488
+ * initial margin allocated across the position's reducing executions when
5489
+ * available, used as the basis for lifetime realized return.
5472
5490
  */
5473
5491
  isolatedMargin?: string | null;
5474
5492
  leverage?: string | null;
@@ -5570,7 +5588,7 @@ export interface components {
5570
5588
  cumFees?: string | null;
5571
5589
  /**
5572
5590
  * Format: int64
5573
- * @description Opaque, non-negative producer-owned version for this position row. Compare only within the same position; higher is newer. 0 is the unranked legacy sentinel and never participates in ordering: treat it exactly as an absent version and fall back to a full field comparison rather than ranking it as oldest. It advances on sequenced position mutations (open, add, reduce, close, funding, margin transfer, liquidation, ADL) and is shared by the persisted read, the WebSocket positions snapshot and a RANKED live position_update frame. A live frame is ranked only when it is a faithful projection of the row persisted at that sequence: in practice the fills that leave a position open. Frames that re-read live risk state after sequencing (funding, margin_added/margin_reduced) and terminal frames (which report size 0 and LIQUIDATED, while the stored row keeps its size and records CLOSED) omit the version even though the mutation did advance the persisted one, so an absent version never implies that nothing was persisted. mark_price, unrealized_pnl, liquidation_price, leverage, maintenance_margin_required and initial_margin_required are UNVERSIONED valuation fields, re-derived per payload rather than served from the versioned row: the version does not advance for them (five move with the oracle mark; leverage does not, being opening notional over posted margin, but the live surfaces derive it while the persisted row serves its stored column, so it can still disagree at an unchanged version) (a valuation-only oracle tick persists nothing; a state-transitioning one, a breach or recovery, does restamp the account's open positions), so the merge rule is per field group — on an equal version skip the versioned fields but still take all six from the newer payload, because discarding a whole payload on an equal version freezes displayed PnL and can leave a stale margin requirement on screen. isolated_margin is the one exception among the versioned fields: the WebSocket positions snapshot overlays it from an independent live matching-engine read rather than the versioned row, so take it from the newest payload on an equal version too or a consumer can retain stale backing. A response served from live matching-engine state reports 0 (unranked): the engine holds the state but not the version.
5591
+ * @description Opaque, non-negative producer-owned version for this position row. Compare only within the same position; higher is newer. 0 is the unranked legacy sentinel and never participates in ordering: treat it exactly as an absent version and fall back to a full field comparison rather than ranking it as oldest. It advances on sequenced position mutations (open, add, reduce, close, funding, margin transfer, liquidation, ADL) and is shared by the persisted read, the WebSocket positions snapshot and a RANKED live position_update frame. A live frame is ranked only when it is a faithful projection of the row persisted at that sequence: in practice the fills that leave a position open. Frames that re-read live risk state after sequencing (funding, margin_added/margin_reduced) and terminal frames (which report size 0 and LIQUIDATED, while the stored row keeps its size and records CLOSED) omit the version even though the mutation did advance the persisted one, so an absent version never implies that nothing was persisted. mark_price, unrealized_pnl, liquidation_price, leverage, maintenance_margin_required and initial_margin_required are UNVERSIONED valuation fields, re-derived per payload rather than served from the versioned row: the version does not advance for them (five move with the oracle mark; leverage does not, being opening notional over posted margin, but the live surfaces derive it while the persisted row serves its stored column, so it can still disagree at an unchanged version) (a valuation-only oracle tick persists nothing; a state-transitioning one, a breach or recovery, persists the account's snapshot and restamps the positions it changed), so the merge rule is per field group — on an equal version skip the versioned fields but still take all six from the newer payload, because discarding a whole payload on an equal version freezes displayed PnL and can leave a stale margin requirement on screen. isolated_margin is the one exception among the versioned fields: the WebSocket positions snapshot overlays it from an independent live matching-engine read rather than the versioned row, so take it from the newest payload on an equal version too or a consumer can retain stale backing. The version advances exactly when the row's versioned content changed at that sequence, a change undone within one persistence batch included; a position a command left unchanged keeps its version, so a RANKED live frame for an untouched sibling of a filled position can carry a higher version than the persisted row while describing identical content — rank it as newer, and nothing changes. A response served from live matching-engine state reports 0 (unranked): the engine holds the state but not the version.
5574
5592
  * @example 918342
5575
5593
  */
5576
5594
  version?: number | null;
@@ -6219,14 +6237,29 @@ export interface components {
6219
6237
  orders?: components["schemas"]["ConditionalOrder"][] | null;
6220
6238
  /**
6221
6239
  * Format: uint32
6222
- * @description Matching conditional orders. Exact up to 10,000 pages of the requested page size (page_size x 10,000 rows) and saturates there, so a caller with more matching conditional orders than the listing can page through reads the cap, not its lifetime total.
6240
+ * @description Matching conditional orders in page-number (offset) mode: exact up to 10,000 pages of the requested page size (page_size x 10,000 rows) and saturates there, so a caller with more matching conditional orders than the listing can page through reads the cap, not its lifetime total. 0 in cursor (pageToken) mode, which runs no COUNT (AIP-158).
6223
6241
  * @example 3
6224
6242
  */
6225
6243
  total?: number | null;
6226
- /** Format: uint32 */
6244
+ /**
6245
+ * Format: uint32
6246
+ * @deprecated
6247
+ * @description Deprecated: current page number (legacy offset mode only; 0 in cursor mode)
6248
+ */
6227
6249
  page?: number | null;
6228
6250
  /** Format: uint32 */
6229
6251
  pageSize?: number | null;
6252
+ /**
6253
+ * @description Cursor for the next page, minted only when a further page exists — the
6254
+ * read over-fetches one row to decide, so there is no "maybe more" state.
6255
+ * Empty on every page-number (legacy) response, and empty on the final
6256
+ * cursor page (including a full final page, since nothing follows it).
6257
+ * Follow it until it comes back empty; that empty token is the definitive
6258
+ * end of the walk, so no extra zero-row request is needed. Do not feed the
6259
+ * empty token back as `page_token` — an empty input `page_token` restarts
6260
+ * the walk from the newest row.
6261
+ */
6262
+ nextPageToken?: string | null;
6230
6263
  };
6231
6264
  ListDelegatedAgentOwnersResponse: {
6232
6265
  /** @description Owners that have an active delegation to the calling agent */
@@ -6435,13 +6468,14 @@ export interface components {
6435
6468
  orders?: components["schemas"]["TwapOrder"][] | null;
6436
6469
  /**
6437
6470
  * Format: uint32
6438
- * @description Matching TWAP orders. Exact up to 10,000 pages of the requested page size (page_size x 10,000 rows) and saturates there, so a caller with more matching TWAP orders than the listing can page through reads the cap, not its lifetime total.
6471
+ * @description Matching TWAP orders in page-number (offset) mode: exact up to 10,000 pages of the requested page size (page_size x 10,000 rows) and saturates there, so a caller with more matching TWAP orders than the listing can page through reads the cap, not its lifetime total. 0 in cursor (pageToken) mode, which runs no COUNT (AIP-158).
6439
6472
  * @example 3
6440
6473
  */
6441
6474
  total?: number | null;
6442
6475
  /**
6443
6476
  * Format: uint32
6444
- * @description Current page number
6477
+ * @deprecated
6478
+ * @description Deprecated: current page number (legacy offset mode only; 0 in cursor mode)
6445
6479
  * @example 1
6446
6480
  */
6447
6481
  page?: number | null;
@@ -6451,6 +6485,17 @@ export interface components {
6451
6485
  * @example 20
6452
6486
  */
6453
6487
  pageSize?: number | null;
6488
+ /**
6489
+ * @description Cursor for the next page, minted only when a further page exists — the
6490
+ * read over-fetches one row to decide, so there is no "maybe more" state.
6491
+ * Empty on every page-number (legacy) response, and empty on the final
6492
+ * cursor page (including a full final page, since nothing follows it).
6493
+ * Follow it until it comes back empty; that empty token is the definitive
6494
+ * end of the walk, so no extra zero-row request is needed. Do not feed the
6495
+ * empty token back as `page_token` — an empty input `page_token` restarts
6496
+ * the walk from the newest row.
6497
+ */
6498
+ nextPageToken?: string | null;
6454
6499
  };
6455
6500
  ManagedMarketAssignment: {
6456
6501
  launchId?: string | null;
@@ -6723,6 +6768,46 @@ export interface components {
6723
6768
  */
6724
6769
  closePosition?: boolean | null;
6725
6770
  };
6771
+ /**
6772
+ * @description Trailing stop leg on an entry order (0XM-2827). Same ratchet semantics as
6773
+ * TrailingStopLeg on the position-attached rail: reduce-only MARKET close,
6774
+ * trigger trails the watermark by trail_bps in the position's favour, fires
6775
+ * through the standard conditional market close path.
6776
+ */
6777
+ ParentTrailingStopLeg: {
6778
+ /**
6779
+ * Format: int32
6780
+ * @description Retracement in basis points behind the best mark reached since arming; integer, 10 to 2000 inclusive.
6781
+ * @example 150
6782
+ */
6783
+ trailBps?: number | null;
6784
+ /**
6785
+ * @description Optional mark level that starts tracking once the entry has fully filled. Omit to start tracking at the first mark after the fill. Rejected at attach time if already met by the current mark.
6786
+ * @example 66000
6787
+ */
6788
+ activationPrice?: string | null;
6789
+ /**
6790
+ * @description Deliberate partial size that never resizes. Mutually exclusive with closePosition; omit both to close the full live position at trigger time.
6791
+ * @example 0.5
6792
+ */
6793
+ quantity?: string | null;
6794
+ /**
6795
+ * @description Resolve the full live position size when triggered. Mutually exclusive with quantity.
6796
+ * @example true
6797
+ */
6798
+ closePosition?: boolean | null;
6799
+ /**
6800
+ * Format: int32
6801
+ * @description Slippage cap in basis points for the triggered MARKET close (TP/SL parity).
6802
+ * @example 1000
6803
+ */
6804
+ slippageToleranceBps?: number | null;
6805
+ /**
6806
+ * @description Optional expiry timestamp (ISO 8601)
6807
+ * @example 2026-06-01T00:00:00Z
6808
+ */
6809
+ expiresAt?: string | null;
6810
+ };
6726
6811
  /**
6727
6812
  * @description A single pending withdrawal in a list response. A lightweight summary — the
6728
6813
  * executable calldata is not included (it does not exist until the withdrawal
@@ -7070,22 +7155,16 @@ export interface components {
7070
7155
  unrealizedPnl?: string | null;
7071
7156
  realizedPnl?: string | null;
7072
7157
  /**
7073
- * @description Open ISOLATED rows: the position's current backing — its risk bucket's
7074
- * allocated collateral adjusted by settled realized PnL and funding paid,
7075
- * net of collateral reserved for the bucket's open orders, clamped at zero
7076
- * (0XM-2558). Partial closes and partial liquidations shrink the posted
7077
- * margin pro-rata while the realized loss stays in the bucket, so this,
7078
- * not the posted margin, is the unrealized-return denominator. Not a hard
7079
- * -100% bound: the liquidation trigger and liquidation_price measure the
7080
- * bucket's whole equity, order reserves included, so with a resting order
7081
- * the return can pass -100% by that order's earmark before liquidation
7082
- * lands; a mark can gap past the backing before the asynchronous
7083
- * liquidation; a fully drained bucket serves "0". Served from the live risk
7084
- * engine; when only persisted state is reachable the value is gross of
7085
- * order reserves. Open CROSS rows fall back to the position's posted
7086
- * margin. Terminal rows: total initial margin allocated across the
7087
- * position's reducing executions when available — the margin basis for
7088
- * lifetime realized return.
7158
+ * @description Open ISOLATED rows: principal committed to the filled position, adjusted
7159
+ * by settled realized PnL, fees and funding, clamped at zero. Collateral
7160
+ * allocated to unfilled orders is excluded. This is the unrealized-return
7161
+ * denominator and the same backing used by isolated liquidation. Placing,
7162
+ * cancelling or resizing an unfilled order does not add position backing.
7163
+ * A price gap can pass the backing before asynchronous liquidation occurs.
7164
+ * Live and persisted reads use the same position-principal basis.
7165
+ * Open CROSS rows: the position's posted margin. Terminal rows: total
7166
+ * initial margin allocated across the position's reducing executions when
7167
+ * available, used as the basis for lifetime realized return.
7089
7168
  */
7090
7169
  isolatedMargin?: string | null;
7091
7170
  leverage?: string | null;
@@ -7187,7 +7266,7 @@ export interface components {
7187
7266
  cumFees?: string | null;
7188
7267
  /**
7189
7268
  * Format: int64
7190
- * @description Opaque, non-negative producer-owned version for this position row. Compare only within the same position; higher is newer. 0 is the unranked legacy sentinel and never participates in ordering: it means the row predates this field or came from a producer that does not stamp it, so treat it exactly as an absent version and fall back to a full field comparison rather than ranking it as oldest. It advances on sequenced position mutations (open, add, reduce, close, funding, margin transfer, liquidation, ADL) and is shared by the persisted read, the WebSocket positions snapshot and a RANKED live position_update frame. A live frame is ranked only when it is a faithful projection of the row persisted at that sequence: in practice the fills that leave a position open. Frames that re-read live risk state after sequencing (funding, margin_added/margin_reduced) and terminal frames (which report size 0 and LIQUIDATED, while the stored row keeps its size and records CLOSED) omit the version even though the mutation did advance the persisted one, so an absent version never implies that nothing was persisted. mark_price, unrealized_pnl, liquidation_price, leverage, maintenance_margin_required and initial_margin_required are UNVERSIONED valuation fields, re-derived per payload rather than served from the versioned row: the version does not advance for them (five move with the oracle mark; leverage does not, being opening notional over posted margin, but the live surfaces derive it while the persisted row serves its stored column, so it can still disagree at an unchanged version) (a valuation-only oracle tick persists nothing; a state-transitioning one, a breach or recovery, does restamp the account's open positions), so the merge rule is per field group — on an equal version skip the versioned fields but still take all six from the newer payload, because discarding a whole payload on an equal version freezes displayed PnL and can leave a stale margin requirement on screen. isolated_margin is the one exception among the versioned fields: the WebSocket positions snapshot overlays it from an independent live matching-engine read rather than the versioned row, so take it from the newest payload on an equal version too or a consumer can retain stale backing. A response served from live matching-engine state reports 0 (unranked): the engine holds the state but not the version.
7269
+ * @description Opaque, non-negative producer-owned version for this position row. Compare only within the same position; higher is newer. 0 is the unranked legacy sentinel and never participates in ordering: it means the row predates this field or came from a producer that does not stamp it, so treat it exactly as an absent version and fall back to a full field comparison rather than ranking it as oldest. It advances on sequenced position mutations (open, add, reduce, close, funding, margin transfer, liquidation, ADL) and is shared by the persisted read, the WebSocket positions snapshot and a RANKED live position_update frame. A live frame is ranked only when it is a faithful projection of the row persisted at that sequence: in practice the fills that leave a position open. Frames that re-read live risk state after sequencing (funding, margin_added/margin_reduced) and terminal frames (which report size 0 and LIQUIDATED, while the stored row keeps its size and records CLOSED) omit the version even though the mutation did advance the persisted one, so an absent version never implies that nothing was persisted. mark_price, unrealized_pnl, liquidation_price, leverage, maintenance_margin_required and initial_margin_required are UNVERSIONED valuation fields, re-derived per payload rather than served from the versioned row: the version does not advance for them (five move with the oracle mark; leverage does not, being opening notional over posted margin, but the live surfaces derive it while the persisted row serves its stored column, so it can still disagree at an unchanged version) (a valuation-only oracle tick persists nothing; a state-transitioning one, a breach or recovery, persists the account's snapshot and restamps the positions it changed), so the merge rule is per field group — on an equal version skip the versioned fields but still take all six from the newer payload, because discarding a whole payload on an equal version freezes displayed PnL and can leave a stale margin requirement on screen. isolated_margin is the one exception among the versioned fields: the WebSocket positions snapshot overlays it from an independent live matching-engine read rather than the versioned row, so take it from the newest payload on an equal version too or a consumer can retain stale backing. The version advances exactly when the row's versioned content changed at that sequence, a change undone within one persistence batch included; a position a command left unchanged keeps its version, so a RANKED live frame for an untouched sibling of a filled position can carry a higher version than the persisted row while describing identical content — rank it as newer, and nothing changes. A response served from live matching-engine state reports 0 (unranked): the engine holds the state but not the version.
7191
7270
  * @example 918342
7192
7271
  */
7193
7272
  version?: number | null;
@@ -7805,6 +7884,21 @@ export interface components {
7805
7884
  * @example 1172836500.00
7806
7885
  */
7807
7886
  openInterestNotional?: string | null;
7887
+ /**
7888
+ * @description Arithmetic mean of the valued gross open-interest notional observations (one per completed UTC minute) over the last 60 completed minutes ending at floor(now to minute); published once at least 95% of those minutes (57) carry a valued sample. Null for spot pairs or below that coverage; a minute without a trade price is unvalued, never zero; known zero is "0". Each sample is gross open position size x latest trade price in quote units. No historical backfill; this window warms after deployment.
7889
+ * @example 1172836500.00
7890
+ */
7891
+ openInterestNotionalAvg1h?: string | null;
7892
+ /**
7893
+ * @description Arithmetic mean of the valued gross open-interest notional observations (one per completed UTC minute) over the last 1440 completed minutes ending at floor(now to minute); published once at least 95% of those minutes (1368) carry a valued sample. Null for spot pairs or below that coverage; a minute without a trade price is unvalued, never zero; known zero is "0". Each sample is gross open position size x latest trade price in quote units. No historical backfill; this window warms after deployment.
7894
+ * @example 1172836500.00
7895
+ */
7896
+ openInterestNotionalAvg24h?: string | null;
7897
+ /**
7898
+ * @description Arithmetic mean of the valued gross open-interest notional observations (one per completed UTC minute) over the last 10080 completed minutes ending at floor(now to minute); published once at least 95% of those minutes (9576) carry a valued sample. Null for spot pairs or below that coverage; a minute without a trade price is unvalued, never zero; known zero is "0". Each sample is gross open position size x latest trade price in quote units. No historical backfill; this window warms after deployment.
7899
+ * @example 1172836500.00
7900
+ */
7901
+ openInterestNotionalAvg7d?: string | null;
7808
7902
  };
7809
7903
  /** @description One UTC-day bucket in a pair's 7-day snapshot. */
7810
7904
  ScreenerSnapshotPoint: {
@@ -7823,6 +7917,11 @@ export interface components {
7823
7917
  * @example 0.85
7824
7918
  */
7825
7919
  priceChangePercent?: string | null;
7920
+ /**
7921
+ * @description Arithmetic mean of the valued open-interest notional observations (one per completed UTC minute) in this completed UTC day; published once at least 95% of its 1440 minutes (1368) carry a valued sample, null for spot pairs or below that coverage. Samples use gross open position size x latest trade price in quote units; a minute without a trade price is unvalued, never zero; known zero remains "0". No historical backfill.
7922
+ * @example 1172836500.00
7923
+ */
7924
+ openInterestNotionalAvg?: string | null;
7826
7925
  };
7827
7926
  SelfTradePreventionDefaultResponse: {
7828
7927
  /**
@@ -8524,6 +8623,41 @@ export interface components {
8524
8623
  */
8525
8624
  quoteAssetName?: string | null;
8526
8625
  };
8626
+ /**
8627
+ * @description Trailing stop leg (0XM-2827). Reduce-only MARKET close whose trigger trails
8628
+ * the best mark price reached since it armed (the "watermark") by `trail_bps`:
8629
+ * for a long, trigger = watermark x (1 - trail_bps/10000) and fires when mark
8630
+ * falls to or below it; for a short, trigger = watermark x (1 + trail_bps/10000)
8631
+ * and fires when mark rises to or above it. The trigger only ever moves in the
8632
+ * position's favour. One trailing stop per position; a second attach is
8633
+ * rejected with a conflict, never a replace. Fires through the same market
8634
+ * close path as a TP/SL (1,200 bps protective band, optional slippage cap).
8635
+ */
8636
+ TrailingStopLeg: {
8637
+ /**
8638
+ * Format: int32
8639
+ * @description Retracement in basis points, integer, 10 to 2000 inclusive.
8640
+ */
8641
+ trailBps?: number | null;
8642
+ /**
8643
+ * @description Optional mark level that starts tracking. Omitted: tracking starts
8644
+ * immediately at the current mark. Present: rejected if the mark has
8645
+ * already reached it; once reached, the watermark seeds at this level.
8646
+ */
8647
+ activationPrice?: string | null;
8648
+ /**
8649
+ * @description Deliberate partial size; mutually exclusive with close_position. Omit both
8650
+ * to close the full live position at trigger time. Same contract as TpSlLeg.
8651
+ */
8652
+ quantity?: string | null;
8653
+ closePosition?: boolean | null;
8654
+ /**
8655
+ * Format: int32
8656
+ * @description Slippage cap for the triggered MARKET close, 0 to 10000 bps (TP/SL parity).
8657
+ */
8658
+ slippageToleranceBps?: number | null;
8659
+ expiresAt?: string | null;
8660
+ };
8527
8661
  TransferCollateralFromMarginAccountRequest: {
8528
8662
  /** @description Parent margin account UUID that releases collateral. */
8529
8663
  marginAccountId?: string | null;
@@ -13112,10 +13246,29 @@ export interface operations {
13112
13246
  /** @description Trading pair identifier (UUID) */
13113
13247
  tradingPairId?: string;
13114
13248
  state?: string;
13115
- /** @description Page number (1-indexed) */
13249
+ /**
13250
+ * @deprecated
13251
+ * @description Deprecated: page number for legacy offset pagination (1-indexed). Use pageToken cursor pagination instead.
13252
+ */
13116
13253
  page?: number;
13117
- /** @description Items per page (max 100) */
13254
+ /** @description Items per page (max 100 in page-number mode; up to 1000 when pageToken is present) */
13118
13255
  pageSize?: number;
13256
+ /**
13257
+ * @description Pagination cursor with three distinct states:
13258
+ * - Omitted: legacy page-number pagination via `page`.
13259
+ * - Empty string (""): start a cursor walk with no prior position, from
13260
+ * the newest conditional order.
13261
+ * - Non-empty: an opaque cursor from a previous response's
13262
+ * `next_page_token`; results resume immediately after that position.
13263
+ *
13264
+ * In either cursor-walk state (empty or non-empty), `page` is ignored and
13265
+ * `total` is not populated — both come back 0, because cursor mode runs no
13266
+ * COUNT (AIP-158). Cursor pages are keyset seeks on `(createdAt, id)`, so a
13267
+ * page size up to 1000 is allowed. Filters must match the request that
13268
+ * produced the token; a token replayed against different filters is
13269
+ * rejected.
13270
+ */
13271
+ pageToken?: string;
13119
13272
  };
13120
13273
  header?: never;
13121
13274
  path?: never;
@@ -13204,13 +13357,32 @@ export interface operations {
13204
13357
  list_twap_orders: {
13205
13358
  parameters: {
13206
13359
  query?: {
13207
- /** @description Page number (1-indexed) */
13360
+ /**
13361
+ * @deprecated
13362
+ * @description Deprecated: page number for legacy offset pagination (1-indexed). Use pageToken cursor pagination instead.
13363
+ */
13208
13364
  page?: number;
13209
- /** @description Items per page (max 100) */
13365
+ /** @description Items per page (max 100 in page-number mode; up to 1000 when pageToken is present) */
13210
13366
  pageSize?: number;
13211
13367
  state?: string;
13212
13368
  /** @description Trading pair identifier (UUID) */
13213
13369
  tradingPairId?: string;
13370
+ /**
13371
+ * @description Pagination cursor with three distinct states:
13372
+ * - Omitted: legacy page-number pagination via `page`.
13373
+ * - Empty string (""): start a cursor walk with no prior position, from
13374
+ * the newest TWAP parent.
13375
+ * - Non-empty: an opaque cursor from a previous response's
13376
+ * `next_page_token`; results resume immediately after that position.
13377
+ *
13378
+ * In either cursor-walk state (empty or non-empty), `page` is ignored and
13379
+ * `total` is not populated — both come back 0, because cursor mode runs no
13380
+ * COUNT (AIP-158). Cursor pages are keyset seeks on `(createdAt, id)`, so a
13381
+ * page size up to 1000 is allowed. Filters must match the request that
13382
+ * produced the token; a token replayed against different filters is
13383
+ * rejected.
13384
+ */
13385
+ pageToken?: string;
13214
13386
  };
13215
13387
  header?: never;
13216
13388
  path?: never;
@@ -14294,6 +14466,13 @@ export interface operations {
14294
14466
  "application/json": components["schemas"]["AttachPositionTpSlResponse"];
14295
14467
  };
14296
14468
  };
14469
+ /** @description Order rate limit exceeded — each attach draws one item from the per-account order-creation budget it shares with order creates (and the budget the account family shares); retry after the interval in details.retryAfter */
14470
+ 429: {
14471
+ headers: {
14472
+ [name: string]: unknown;
14473
+ };
14474
+ content?: never;
14475
+ };
14297
14476
  };
14298
14477
  };
14299
14478
  get_pulse: {