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

# V1.0.75

# Monaco Protocol SDK v1.0.75

This release moves the remaining page-number listings to **cursor pagination**, makes the **application reporting endpoints public** (selected by `clientId`, no server key), and lists **book orders only** from `GET /api/v1/orders`. It adds **periodic position valuation frames**, **`openedAt` on positions**, **sub-account collateral transfers**, **isolated-only markets**, a **`connecting` WebSocket status** with attempt context, and paged PitPass downline earnings that report every referral level. **Action items:** stop sending `page` and walk listings with `pageToken` / `nextPageToken`; pass `clientId` to the application listings and drop `setServerKey`; list TWAP and conditional orders with their own methods; page `earningsBySource` and read `summary.byLevel`; accept the new `PRICE_BAND` and `SLIPPAGE_TOLERANCE` terminal reasons; upgrade before you rely on valuation frames.

## Breaking

### Page-number pagination is removed

The `page` request field is gone from these listings, all of which now walk with `pageToken`: omit it (or send `""`) to start, then follow `nextPageToken` until it comes back empty.

* Positions: `sdk.positions.listPositions` (`GET /api/v1/positions`; gRPC `PositionsService.ListPositions`) and `listPositionHistory` (`GET /api/v1/positions/history`).
* Margin accounts: `sdk.marginAccounts.listMarginAccounts` (`GET /api/v1/margin/accounts`), `getMarginAccountMovements` (`GET /api/v1/margin/accounts/{marginAccountId}/movements`) and `getParentMarginAccountMovements` (`GET /api/v1/margin/parent-margin-account/movements`).
* Account reads: `sdk.profile.getPaginatedUserMovements` (`GET /api/v1/accounts/movements`), `getUserBalances` (`GET /api/v1/accounts/balances`) and `listFundingPayments` (`GET /api/v1/accounts/funding-payments`).
* Funding history: `sdk.market.listFundingHistory` (`GET /api/v1/market/pairs/{tradingPairId}/funding/history`) and `listAllFundingHistory` (`GET /api/v1/market/funding/history`).
* Application listings: `sdk.applications.listApplicationOrders`, `listApplicationUsers`, `listApplicationMovements` and `listApplicationBalances` (`GET /api/v1/applications/orders`, `/users`, `/movements`, `/balances`).

Over REST a request that still sends `page` is rejected with `400`. Over gRPC protobuf drops the unknown field, so an old client keeps working but reads the **first** cursor page on every call; remove `page` and upgrade your generated stubs. The TypeScript SDK rejects `page` on every listing above with a `ValidationError` before sending, so a caller that handles only `400` sees a client-side error instead.

`pageSize` accepts 1 to 1000 (was 1 to 100). Defaults are unchanged (20, or 50 for funding history). The funding, balances, margin-account and application listings now reject a larger value instead of clamping it. The `page` response field is gone everywhere. Counts change by listing:

* `total` is gone from position history, margin-account movements, and application orders and movements.
* Positions, account movements, funding payments, funding history, application users and application balances keep `total` (and `totalPages` where they had it), bounded by a server count ceiling, with a new `totalCapped` flag that is `true` when more rows matched. Do not drive a paging loop from `total`.
* Balances and margin accounts keep an exact `total` with no `totalCapped`.

Some sort orders change so a walk never repeats or drops a row. Positions sort newest-first by open time (an `OPEN` filter walks by margin account, trading pair and position id), and funding payments by `(createdAt, id)` descending. Funding history sorts by `(settledAt, id)`, application users by user id and application balances by balance id. Balances and margin accounts follow a fixed key order. Rows with no recorded timestamp are no longer listed in margin-account movements, application movements and funding payments.

`@0xmonaco/react`'s `useUserMovements` drops its `page` option and does not take a cursor: it reads one newest-first page and keeps it current from the `movements` channel. Walk the full history with `sdk.profile.getPaginatedUserMovements`. See [Positions](/sdk/typescript/positions), [Profile](/sdk/typescript/profile) and [Margin Accounts](/sdk/typescript/margin-accounts).

### Application reporting endpoints are public

`listApplicationOrders`, `listApplicationUsers`, `listApplicationMovements`, `listApplicationBalances` and `getApplicationStats` (`GET /api/v1/applications/orders`, `/users`, `/movements`, `/balances`, `/stats`; gRPC `ApplicationsService`) no longer use the `x-server-key` header, and application secret keys are no longer issued. Each call takes a required `params` with `clientId`, the public client ID you log in with. A missing `clientId` is `400`, and an unknown or inactive one is `404`. The five share a per-client-IP limit of 60 requests per minute (burst 120); over it REST answers `429` with `Retry-After` and gRPC answers `RESOURCE_EXHAUSTED` with a `google.rpc.RetryInfo` delay. The SDK removes `setServerKey`, and `AppUser` no longer carries `email`, `canWithdraw` or `isBanned`. See [Applications](/sdk/typescript/applications).

### `GET /api/v1/orders` lists book orders only

`sdk.trading.getPaginatedOrders` and `iterateOrders` (`GET /api/v1/orders`; gRPC `OrdersService.ListOrders`) return limit and market orders only, under every `status` and `tradingMode` filter, and `total` counts only those. `Order.orderType` is `"LIMIT" | "MARKET"` again: the `ListedOrderType` alias, its `"TWAP"` / `"CONDITIONAL"` members and the optional `Order.twap` / `Order.conditional` fields are removed. List TWAP parents with `sdk.trading.listTwapOrders` and TP/SL orders with `sdk.trading.listConditionalOrders`; both are unchanged. The request parameters and cursor contract are unchanged. See [Trading](/sdk/typescript/trades).

### PitPass downline earnings are paged

`sdk.pitpass.getMyReferralDownline(params?)` (`GET /api/v1/pitpass/referrals/me/downline`; gRPC `TraderCodeService.GetMyReferralDownline`; React `useMyReferralDownline`) pages `earningsBySource`: a call without paging returns the first 100 rows. Pass `pageSize` (1 to 500, default 100) and `pageToken`, and follow `nextPageToken` until it is empty. Rows are ordered by `totalEarned` descending; a wallet that traded through several applications is merged within a page and can appear again on a later page.

`summary.byLevel` lists `{ level, earned }` for every level with earnings, across every source, on every page. `summary.level1Earned`, `level2Earned` and `level3Earned` are deprecated: they still report levels 1 to 3 and nothing deeper. `getMyReferralPosition`'s `upline` holds as many entries as PitPass currently rewards levels (at most 10), and `getMyReferralTree` expands nodes down to that depth. See [PitPass](/sdk/typescript/pitpass).

### New order terminal reasons

`terminalReason` gains `PRICE_BAND` (the protective price band stopped the order and its remainder was cancelled) and `SLIPPAGE_TOLERANCE` (the order's own `slippageToleranceBps` was the tighter bound). Both used to end `CANCELLED` with no reason. Code that switches exhaustively on `terminalReason` must accept them.

## Added

### Position valuation frames

`sdk.ws.positions(handler, tradingPairId?, onSnapshot?, onValuation?)` takes an optional `onValuation` callback for the channel's periodic `position_valuation` frames (`PositionValuationEvent`). Each frame carries `positionId`, `marginAccountId`, `tradingPairId`, `markPrice`, `unrealizedPnl`, `liquidationPrice` (`null` when it cannot be derived), `initialMarginRequired`, `maintenanceMarginRequired` and `valuedAt`, and no size, side, status or version. Apply a valuation only to a position you hold as `OPEN` whose `updatedAt` is earlier than `valuedAt`; ignore it otherwise. `handler` still receives `position_update` frames only, and without `onValuation` valuation frames are dropped silently. Earlier SDK versions log one parse error per valuation frame, so upgrade before you rely on them. See [WebSockets](/sdk/typescript/websockets).

### `openedAt` on positions

Positions report the instant they opened: the fill that took exposure from zero to non-zero. `Position.openedAt` (`string | null`; `null` when unknown) is on `listPositions`, `getPosition` and the other position reads, and `openedAt` is on `positions` WebSocket events and snapshot rows (absent when the frame does not carry it). It never changes for a `positionId`; a flip opens a new position. Time held is `now - openedAt` while `OPEN` and `updatedAt - openedAt` once terminal. See [Positions](/sdk/typescript/positions).

### Sub-account collateral transfers

`sdk.marginAccounts.transferCollateralToSubAccount(marginAccountId, amount)` (`POST /api/v1/margin/sub-accounts/{marginAccountId}/collateral/transfer-in`; gRPC `MarginAccountsService.TransferCollateralToSubAccount`) moves collateral from the default margin account into a sub-account, and `transferCollateralFromSubAccount` (`.../collateral/transfer-out`; gRPC `TransferCollateralFromSubAccount`) moves it back. Both take a sub-account UUID and a positive decimal amount and resolve to a `TransferMarginCollateralResponse`; the default margin account itself is refused with `400`. The MCP server adds `transfer_collateral_to_sub_account` and `transfer_collateral_from_sub_account`. See [Margin Accounts](/sdk/typescript/margin-accounts#sub-accounts).

### Isolated-only markets

`TradingPair.isolatedOnly` (`GET /api/v1/market/pairs`, `/market/pairs/{tradingPairId}`) marks a market that accepts cross margin only to reduce a position. A `CROSS` order that is not reduce-only is rejected with `400` / `INVALID_ARGUMENT` and the error code `CROSS_MARGIN_NOT_ALLOWED`; open with `marginMode: "ISOLATED"` instead. A copy that would land in a cross risk bucket on such a market is skipped with `MARKET_STATE` and does not count toward the follower skip limit. See [Trading](/developers/trade).

### `connecting` status and connection-attempt context

`onStatusChange` now reports `"connecting"` when a connection opens outside a retry cycle (the constructor's auto-connect, a reconnect after terminal authentication loss, and a `connect()` after a terminal `"disconnected"`), before any other status for that connection. Every status change also passes a `WebSocketStatusInfo`: `attempt`, `hasConnected` and, on `"reconnecting"`, `nextRetryDelayMs`. `"reconnecting"` with `hasConnected: false` means the first connect is still failing. With a finite `maxReconnectAttempts`, running out reports one `"disconnected"` whose `attempt` equals the cap, and a later `connect()` starts a fresh retry budget. Behavior changes: `getStatus()` returns `"reconnecting"` while a retry is opening, and an error thrown or rejected by `onStatusChange` is logged instead of propagated. See [WebSockets](/sdk/typescript/websockets).

## Changed

### Fee tiers count volume floors

`sdk.fees.getMyFeeTier` (`GET /api/v1/fees/tier`; gRPC `FeesService.GetMyFeeTier`) resolves `currentTierLevel` and `volumeToNextTier` from the higher of the wallet's weighted 14-day volume and any volume floor Monaco has set on it. `weightedVolume14d`, `spotVolume14d` and `perpVolume14d` still report recorded volume, so a wallet with a floor can show a tier above what `weightedVolume14d` alone reaches. No fields changed. See [Trading](/sdk/typescript/trades).

### Margin order admission prices the real cost

A crossing order is charged its initial margin at the mark, the loss each fill takes against the mark, and its taker fee. A resting order is charged its initial margin at its limit, its maker fee, and the loss it would take against the live mark. Only the part of an order that opens or flips a position is charged, so a close is never refused for its loss. The parent margin account's automatic draw funds exactly what a risk bucket's orders need beyond its own equity, and every release returns the rest. An adjust-margin transfer prices the amount at the current mark, so the position's initial margin requirement rises by exactly the amount. No request or response shape changed. See [Margin](/trading-mechanics/perps).

### Collateral bounds round down

`withdrawableCollateral` and `availableOrderCollateral` on margin-account and risk-bucket rows, and `newWithdrawableCollateral` on transfer responses, round down to the collateral asset's decimals. A transfer of exactly the printed `withdrawableCollateral` is accepted; `availableOrderCollateral` is the order-admission bound, not a transfer bound. Risk-bucket figures (`isolatedMargin`, equity, `freeCollateral` and the cross `liquidationPrice`) no longer count the parent's automatic draw for a resting order against the position.

## Fixed

* **Account-to-account transfers** — `transferMarginCollateral` between two of your own margin accounts no longer fails with `400` "token is not a valid 20-byte address"; the `asset` field is accepted and ignored on that route.
* **TP/SL on a just-opened position** — `sdk.positions.attachPositionTpSl` (`POST /api/v1/positions/{positionId}/tp-sl`) no longer answers `404` while the new position is still being persisted.
* **Adding margin right after open** — `transferCollateralToRiskBucket` (Adjust Margin) and `sdk.copyTrading.addFollowPositionMargin` credit a position that has just opened instead of treating the add as a plain risk-bucket allocation.
* **Margin TWAP on a new risk bucket** — `sdk.trading.createTwapOrder` on an isolated risk bucket that does not exist yet, or is closed, moves no collateral up front; each slice draws what it needs as it reserves.

## Upgrade

```bash theme={null}
npm install @0xmonaco/core@1.0.75 @0xmonaco/types@1.0.75 @0xmonaco/react@1.0.75
# or bun
bun add @0xmonaco/core@1.0.75 @0xmonaco/types@1.0.75 @0xmonaco/react@1.0.75
```

Remove every `page` argument and loop on `nextPageToken`. Replace `setServerKey` with a `clientId` on each application listing call. Move TWAP and TP/SL reads off `getPaginatedOrders`, read `summary.byLevel` for referral earnings, and add `PRICE_BAND` and `SLIPPAGE_TOLERANCE` to any exhaustive `terminalReason` handling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.