> ## 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.76

# Monaco Protocol SDK v1.0.76

This release finishes the move to **cursor pagination** on the public trades listing and the pending-withdrawal, managed-market and BuilderCodes payout listings, and makes `sdk.trades.getTrades` resolve to a `{ trades, nextPageToken }` envelope. Perp risk tiers report **`maxPositionNotional` as a USD notional cap**, and markets can carry an optional USD position cap and open-interest cap checked at admission. BuilderCodes reads and claims no longer depend on the revenue-share switch. The WebSocket `market_stats` and `instruments` channels carry more market context, and an edited order's `OrderPlaced` reports the fill it carried over. **Action items:** stop sending `page` to these four listings and walk them with `pageToken` / `nextPageToken`; read `.trades` from `getTrades`; read `maxPositionNotional` instead of `maxPositionSize`; handle a successful BuilderCodes config read with `buildercodesEnabled: false`.

## Breaking

### Page-number pagination is removed from four more listings

The `page` request field is gone from these listings, which now walk with `pageToken`: omit it (or send `""`) to start, then follow `nextPageToken` until it comes back empty. Each walk is one ordered read, so an empty `nextPageToken` is a definitive end.

* Public trades: `sdk.trades.getTrades` (`GET /api/v1/trades/{tradingPairId}`; gRPC `TradesService.GetTrades`). `pageSize` defaults to 25. The walk seeks on `(executedAt, id)`, so a page never repeats or skips a trade when new fills land mid-walk, and still covers the recent trades window rather than archived history.
* Pending withdrawals: `sdk.withdrawals.listPendingWithdrawals` (`GET /api/v1/withdrawals`; gRPC `WithdrawalsService.ListPendingWithdrawals`). Default 20, newest first.
* Managed-market assignments: `sdk.managedMarkets.listAssignments` (`GET /api/v1/managed-markets/assignments`; gRPC `ManagedMarketsService.ListAssignments`). Default 100, **oldest** first.
* BuilderCodes payouts: `sdk.buildercodes.listPayouts` (`GET /api/v1/buildercodes/payouts`; gRPC `BuildercodeRewardsService.ListBuildercodePayouts`). Default 20.

`pageSize` accepts 1 to 1000 (was 1 to 100), and a larger value is rejected instead of clamped. The `page` response field is gone; `total` (and `totalPages` on pending withdrawals and payouts) stays exact. Over REST a request that still sends `page` is rejected with `400`. Over gRPC an old stub's `page` is discarded as an unknown field and every call reads the **first** page, so regenerate your stubs. The TypeScript SDK and the MCP server reject a leftover `page` before sending.

**Payout ordering changes.** `listPayouts` now walks `(createdAt, id)` descending. It never skips or repeats a credit, but it is not chronological inside one persistor batch: every credit a batch writes shares a timestamp and the `id` tie-break is random, so a later fill can be listed ahead of an earlier one. Across batches the order is still newest-first. See [BuilderCodes](/sdk/typescript/buildercodes).

### `getTrades` returns an envelope

`sdk.trades.getTrades(tradingPairId, options)` resolves to `{ trades, nextPageToken }` instead of `TradeEvent[]`. `options.page` is gone and `options.pageToken` is new; passing `page` throws a `ValidationError` before any request is sent. Callers that used the array directly read `.trades`. The trades and their order (newest first) are unchanged. The MCP `get_trades` tool takes `pageToken` and returns `nextPageToken`, and its strict input schema rejects `page`. `useTradeFeed` is unchanged. See [Market Data](/sdk/typescript/market).

### `maxPositionNotional` is a USD notional cap

On `getPerpMarketConfig` (`GET /api/v1/market/pairs/{tradingPairId}/perp/config`), each `RiskTier.maxPositionNotional` is now the most USD notional a position may hold at that tier's `maxLeverage`: the next tier's `lowerBoundNotional`, or the market's position cap on the top tier (absent when the market is uncapped). It used to carry a base-asset quantity under the notional name. `maxPositionSize` is deprecated and no longer set. See [Margin ladders](/trading-mechanics/perps#margin-ladders).

## Added

### Market position and open-interest caps

A perp market can carry an optional USD **position cap** and an optional USD **open-interest cap**. Both are checked at admission only, priced at the mark. An order that would take its risk bucket's position plus its same-side resting orders past the position cap is rejected with `position cap exceeded: …`, and one whose opening quantity would take the market's open interest past its cap with `open interest cap reached: …`, both `400` / `INVALID_ARGUMENT`. A position the mark carries past a cap can still be reduced, and a reduce-only order always passes. The per-base-quantity position size limit is retired, so a market is uncapped unless configured otherwise. See [Margin ladders](/trading-mechanics/perps#margin-ladders).

### More fields on `market_stats` frames

`sdk.ws.marketStats` events and snapshot rows carry `openInterestHeadroom` (what is left of the open-interest cap at the mark, in USD notional, never below zero) and `marketStatus` (the same label as the market's `marketStatsAll` row; pass unrecognized values through). Perp frames add `fundingIntervalSeconds` and `lastFundingTime` (a millisecond epoch, absent before the first settlement). `openInterestLimit` is now the cap in USD notional; it and `openInterestHeadroom` are omitted when the market is uncapped. A perp market is always published: until its open interest is known, `openInterest` and `openInterestHeadroom` are omitted (never `"0"`) and every other field is still sent. See [WebSockets](/sdk/typescript/websockets).

### Asset identity on `instruments` frames

`sdk.ws.instruments` snapshot rows and live frames carry `baseAssetId`, `quoteAssetId`, `baseToken`, `quoteToken`, `baseAssetName`, `quoteAssetName`, `baseDecimals` and `quoteDecimals` on every market, plus `minLeverage` on perps, so a client can label a market and scale its amounts without parsing `symbol` or calling REST. All are optional; a frame from an older server arrives with them `undefined`.

### Edited orders report their carried fill

Replacing a partly filled order keeps its fills. The replacement's `OrderPlaced` now carries `filledQuantity`, `filledQuantityRaw` and `averageFillPrice` from the original, with the order's total `quantity` and `PARTIALLY_FILLED`, as `getOrder` reports it. Its fill frames report the total, cumulative fill and average across every fill. A maker fill's `averageFillPrice` is now the order's cumulative average rather than that trade's price, which stays in `executionPrice`. See [WebSockets](/sdk/typescript/websockets).

### Per-market perp price band

A perp market can be configured with its own price band, from 100 to 2,500 bps, which replaces both the 1,000 bps placement default and the 1,200 bps triggered-leg default on that market. Markets without one keep the defaults. See [Perp price band](/trading-mechanics/perps#perp-price-band).

## Changed

### BuilderCodes reads and claims are not switch-gated

`getConfig`, `listPayouts`, `getPayoutSummary`, `getRewardsBalance`, `claimBuildercodeRewards` and `listBuilderFeeChanges` (`GET /api/v1/buildercodes/config`, `/payouts`, `/payouts/summary`, `/rewards/balance`, `/builder-fee/changes`, `POST /api/v1/buildercodes/rewards/claim`) work whether or not the revenue share is on. They return `403` / `PERMISSION_DENIED` only for a delegated session or, where it applies, a caller that is not the application's payout wallet. `setBuilderFee` (`PUT /api/v1/buildercodes/builder-fee`) is refused only while both the revenue share and builder fees are off. `getConfig`'s `buildercodesEnabled` reports whether the revenue share is on and can be `false` on success. See [BuilderCodes](/developers/buildercodes).

### Overload refusals on cancels

When the engine's work budget is full, cancels, like creates and replaces, can be refused with a retryable `503` and error code `OVERLOADED`. Cancels keep a reserved share of that budget, so they are refused last.

### Direct vault deposits need the exact payload

A deposit made straight to the vault contract must carry the exact `applicationData` that `encodeDepositApplicationData()` (from `@0xmonaco/contracts`) produces. Apart from Monaco's own insurance-fund top-up form, any other JSON-shaped payload is credited to the spot wallet of Monaco's default application rather than yours. SDK deposits are unaffected. See [Deposit Tokens](/deposit/deposit-tokens).

## Fixed

* **`useUserOrders` and edited orders** — the replacement of a partly filled order now shows the fill and average it carried over, instead of zero fill until a refresh.

## Upgrade

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

Remove `page` from `getTrades`, `listPendingWithdrawals`, `listAssignments` and `listPayouts` and loop on `nextPageToken`. Read `.trades` from `getTrades`. Read `maxPositionNotional` as a USD notional and drop `maxPositionSize`. Treat `buildercodesEnabled: false` as a valid config response.


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