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

# Monaco Protocol SDK v1.0.42

This release adds typed WebSocket helpers for the `market_stats` and `account` channels so you no longer hand-roll the raw subscription and key-mapping; lets the candlestick endpoint chart the mark-price series alongside the trade-derived one; and tightens `clientOrderId` so a value can be held by only one of your resting orders at a time. One thing to act on: if you reuse a `clientOrderId` across two of your own resting orders it is now rejected — that rejection identifies the order already holding the handle, but its absence is not evidence that an earlier submit failed, so read the action item before using it to decide whether to retry.

## Added

### Typed `market_stats` and `account` WebSocket helpers

`@0xmonaco/core` gains three typed subscription helpers so the `market_stats` and `account` channels no longer require the raw WebSocket protocol:

* `sdk.ws.marketStats(tradingPairId, handler)` — per-market statistics for one pair (public): index / mark / mid prices, best bid/ask, open interest and its limit, last trade, 24h volume / high / low and price change, and funding state.
* `sdk.ws.marketStatsAll(handler)` — a slower-cadence reduced summary for every market in a single frame (public), each row carrying a `marketStatus` label (`TRADABLE`, `POST_ONLY`, `HALTED`, `NOT_READY`, or `UNKNOWN`).
* `sdk.ws.account(handler)` — the authenticated `account` channel: a margin account's health (equity, collateral, free collateral, margin ratio, maintenance requirement).

`@0xmonaco/types` adds the shapes these deliver — `MarketStatsEvent`, `MarketStatsData`, `MarketStatsAllEvent`, `MarketStatsSummary`, and the `MarketStatus` union — with perp-only fields optional so spot markets flow through the same helpers. The helpers hand you the camelCased ergonomic shape; string decimals stay strings and omitted (perp-only) fields surface as `undefined`. As in 1.0.41, the `account` producer is gated off by default and not yet enabled in the deployed environments, so `sdk.ws.account` subscribes successfully but frames arrive only once the producer is enabled.

### Mark-price candlestick series (`priceType`)

The candlestick endpoint accepts an optional `priceType` (`getCandlesticks`'s `GetCandlesticksParams.priceType` in `@0xmonaco/core` / `@0xmonaco/types`; the `priceType` query parameter on `GET /api/v1/market/pairs/charts/candlestick/{tradingPairId}/{interval}`; `GetCandlesRequest.price_type` on gRPC `MarketService.GetCandles`). `"trade"` (the default) returns the trade-derived OHLCV series, exactly as before. `"mark"` returns the mark-price series for margin pairs: a close-only series where each candle's open, high, low, and close are the minute's closing mark and volume is `0`. Requesting `"mark"` on a spot pair returns a `400`.

## Changed

### `clientOrderId` is unique among your resting orders

A `clientOrderId` may no longer be held by two of your resting orders at once. "Resting" means sitting on the book — an order that never rests never claims the handle. On a single create or replace (`placeLimitOrder` / `placeMarketOrder` / `replaceOrder` in `@0xmonaco/core`; `POST /api/v1/orders`, `PUT /api/v1/orders/{orderId}`; gRPC `CreateOrderRequest` / `ReplaceOrderRequest`; the `place_limit_order` / `place_market_order` / `replace_order` MCP tools), reusing a `clientOrderId` still carried by another of **your own** resting orders is rejected with HTTP `409` / gRPC `ALREADY_EXISTS`, code `CLIENT_ORDER_ID_CONFLICT`; the message names the order already holding it. In a batch (`batchCreate` / `batchReplace`; `POST /api/v1/orders/batch-create` and `.../batch-replace`) the conflict is a **per-item** failure — the request returns `200` / `OK` and only the offending item carries `error.code` `CLIENT_ORDER_ID_CONFLICT` in its result slot — so inspect `results[]` rather than waiting for a transport-level `409`. (A *malformed* handle is not reported the same way on both endpoints: `batchCreate` fails only that item with `INVALID_CLIENT_ORDER_ID`, while `batchReplace` validates every handle up front and rejects the whole request with a `400`.)

<Warning>
  **Correction.** This section originally told you to resubmit the request after a lost response and read the `CLIENT_ORDER_ID_CONFLICT` as proof the first attempt landed. That is unsafe and the text below has been corrected. Only a **resting** order holds a `clientOrderId`, so the conflict cannot fire for an attempt that filled on arrival, was `IOC`/`FOK`, or was a `MARKET` order — and a resubmission in those cases is accepted as a new order that **can execute again**, potentially doubling your size. Reconcile against the order WebSocket stream instead; see [Client Order IDs](/developers/trade#client-order-ids).
</Warning>

**Where the conflict fires it is a reliable signal.** If you resubmit with a `clientOrderId` still held by one of your resting orders, `CLIENT_ORDER_ID_CONFLICT` proves that order exists and is still resting — the check runs in the matching engine against live state, not against replicated history, so unlike an order-list lookup it cannot report "not found" for an order that did land. Read the named order rather than placing a second one.

**Its absence proves nothing, so do not resubmit to probe for it.** The handle is claimed only when an order comes to rest and is released the moment it reaches a terminal state, so no conflict is raised when the first attempt filled, was cancelled, was rejected, or never rested at all. A resubmission then places a genuinely new order and can execute a second time. After a lost response, reconcile on the order stream (`sdk.ws.userOrders`), which carries your `clientOrderId` on every event including orders that never rested, and resubmit only once you have positive evidence the intent did not land.

**Scope is per user, among resting orders only.** Two different users may hold the same value at once, and the value frees the moment the order holding it reaches a terminal state (filled, cancelled, expired, rejected), so a stable per-quote label can be reused indefinitely. A replacement may restate the original's handle — the original releases it as the replacement claims it, matching the existing guidance to restate the value on every replace. Orders that carry no `clientOrderId` are unaffected, and orders already resting when this shipped keep whatever handle they carry.

## Upgrade

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

The MCP server ships at `1.0.42` too; it runs via `npx -y @0xmonaco/mcp-server`, so restarting your assistant picks up the new version. Nothing in this release is breaking. The one thing worth acting on: if you assign a `clientOrderId` and a single create's response is lost, **do not blind-resubmit** — reconcile on the order stream (`sdk.ws.userOrders`) first. A `409` / `CLIENT_ORDER_ID_CONFLICT` confirms an order is still resting under that handle, but no conflict does not mean nothing landed: an order that filled on arrival or never rested releases the handle, and resubmitting can execute again.


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