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

# Changelog

> Product updates and release notes for Arcus

<Update label="July 1, 2026" description="testnet-v1.1.98">
  ## Breaking changes

  **Market `category` values are now upper-case and add `CRYPTO`.** The `category` field on [`GET /v1/api-meta/overview`](/api-reference/marketmetadata/get-market-overview) and [`GET /v1/api-meta/spot/overview`](/api-reference/marketmetadata/get-spot-market-overview) now returns `EQUITIES`, `COMMODITIES`, `INDICES`, or `CRYPTO`, replacing the previous lower-case `stocks` / `commodities` / `indices`. Still omitted for underlyings outside the classified universe.

  ## New features

  **Per-subaccount rate-limit snapshot on write responses.** [`POST /v1/placeOrder`](/api-reference/exchange/place-order), [`POST /v1/batchPlaceOrders`](/api-reference/exchange/place-batch-orders), [`POST /v1/cancelOrder`](/api-reference/exchange/cancel-order), [`POST /v1/batchCancelOrders`](/api-reference/exchange/batch-cancel-orders), [`POST /v1/cancelAllOrders`](/api-reference/exchange/cancel-all-open-orders), and [`POST /v1/modifyOrder`](/api-reference/exchange/modify-order) now return a `rateLimit` object (`pool` — `order` or `cancel` — and `remaining` tokens after the request) on both REST and WebSocket, so clients can track their remaining budget without an extra call. `remaining` can be `0` or negative while the request still succeeds when the account is on the drip throttle; `-1` is a sentinel meaning the account layer was not enforced (bypass allowlist, shadow mode, fail-open on a Redis error, or IP-only).

  **`clientId` echo on rate-limit rejections.** The `429` body now echoes the request's `clientId` (single-order endpoints) or `clientIds` (batch endpoints, positionally aligned with the submitted array), so a client firing concurrent requests can correlate the rejection to a specific order or batch.

  **New modify rejection reason.** `MODIFY_WOULD_CROSS_OUTSIDE_RTH_TRADING_BOUNDARY` — a non-crossing `modifyOrder` reprice rejected because the new price violates the active off-hours trading band. Unlike `PRICE_WILL_EXCEED_MAXIMUM_OUTSIDE_RTH_TRADING_BOUND` (the crossing cancel-replace path, which removes the original), the original order stays resting on the book unchanged.

  ## Updates

  **Deterministic market ordering documented.** [`GET /v1/markets`](/api-reference/public/get-markets) now documents that markets are returned sorted by ascending `marketId`, and the mids map on [`GET /v1/mids`](/api-reference/public/get-all-mid-prices) is ordered by ascending `marketId` and includes only ONLINE markets (OFFLINE markets are omitted).
</Update>

<Update label="June 30, 2026" description="testnet-v1.1.96">
  ## Breaking changes

  **Position-tiered margin fields removed.** [`GET /v1/api-meta/markets`](/api-reference/marketmetadata/get-market-metadata) and the [`markets`](/api-reference/channels#markets) WebSocket channel no longer return `transferMarginFraction`, `incrementalInitialMarginFraction`, `incrementalPositionSize`, `baselinePositionSize`, or `maxPositionSize`. Initial margin is no longer scaled by position-size brackets in the published market schema; `initialMarginFraction`, `maintenanceMarginFraction`, and the off-hours variants remain.

  **`minOrderSize` and `maxOrderSize` removed.** The same market reads drop `minOrderSize` and `maxOrderSize`, and `minOrderSize` is no longer a required field. Per-market order sizing is now expressed through `minOrderNotional` (the \$5 minimum-notional floor introduced in testnet-v1.1.93) and `stepSize`.
</Update>

<Update label="June 29, 2026" description="testnet-v1.1.93">
  ## Breaking changes

  **All-traders leaderboard replaces the affiliate volume leaderboard.** `GET /v1/affiliate/volumeleaderboard` (`getVolumeLeaderboard`) is gone, replaced by [`GET /v1/leaderboard`](/api-reference/public/get-the-all-traders-leaderboard) (`getTraderLeaderboard`). A new `sortBy` query param (`volume`, `pnl`, or `fees`; default `volume`) chooses the ranking column, and every row now carries `volume`, `feesPaid`, and `pnl` (realized only) together, computed in one query so the three columns are always mutually consistent. The `window` (`all`/`30d`/`24h`, default `30d`) and `limit` (max 100, no cursor) semantics are unchanged.

  **Notification timestamps are now decimal strings.** On [`GET /v1/api-meta/notifications`](/api-reference/notifications/list-notifications-for-an-address), `createdAtNs` is now a string — the value exceeds 2^53 and a JSON number would lose precision in JS clients. Pass it back verbatim as the `before_ns` cursor (also now a decimal-string query param) and inside `ids[].created_at_ns` on [`:markSeen`](/api-reference/notifications/mark-notifications-as-seen); a truncated value targets the wrong row. `:markSeen` still accepts a bare number for backward compatibility.

  **Minimum order notional enforced.** [`POST /v1/placeOrder`](/api-reference/exchange/place-order) and [`POST /v1/batchPlaceOrders`](/api-reference/exchange/place-batch-orders) now reject position-opening orders whose notional (`quantity` × `price`) is below **\$5** with `InvalidRequest`. Reduce-only orders (including TPSLs) are exempt. The per-market floor is published as `minOrderNotional` on [`GET /v1/api-meta/markets`](/api-reference/marketmetadata/get-market-metadata).

  **API key `keyName` removed.** [`POST /v1/createApiKey`](/api-reference/onboarding/create-api-key) no longer accepts or returns the optional `keyName` label.

  ## New features

  **Deposit & withdrawal notifications.** The notification inbox now surfaces `deposit` and `withdrawal` events through a new `NotificationTransferPayload` (`subaccountIdx`, `amount`, `netQuoteBalance`, `operationId`). These events are not market-scoped, so the enclosing `marketId` is `0`.

  **Off-hours trading-band fields.** [`GET /v1/api-meta/markets`](/api-reference/marketmetadata/get-market-metadata) and the [`markets`](/api-reference/channels#markets) WebSocket channel now expose `currentSettlementPrice`, `currentTradingBound`, and `nextTradingBound` for equity-class markets while outside regular trading hours (omitted in-RTH and for 24/7 crypto markets).

  **Lifetime volume & fees on the fee-tier read.** [`GET /v1/feetiers`](/api-reference/public/get-fee-tier-table) now returns `lifetimeVolume` and `lifetimeFeesPaid` alongside the existing 14-day `rollingVolume`.

  ## Updates

  **Open interest is now populated.** `openInterest` on [`GET /v1/api-meta/markets`](/api-reference/marketmetadata/get-market-metadata) and the `markets` WebSocket channel now reports the total size of open long positions (equal to total short, in base-asset units), refreshed from a periodic snapshot, instead of the previous placeholder `"0"`.

  **Market category on overview reads.** [`GET /v1/api-meta/overview`](/api-reference/marketmetadata/get-market-overview) and [`GET /v1/api-meta/spot/overview`](/api-reference/marketmetadata/get-spot-market-overview) add a `category` field (`stocks`, `commodities`, or `indices`) for classified equity-class underlyings.
</Update>

<Update label="June 25, 2026" description="Mainnet live">
  ## New features

  **Mainnet is live.** The production API is now serving at `https://api.arcus.xyz` (REST) and `wss://api.arcus.xyz/v1/ws` (WebSocket), selectable from the server dropdown on every endpoint page. Testnet (`api.testnet.arcus.xyz`) remains available, and the two environments share identical paths, payloads, and signing — only the host differs. The code samples and API playground throughout the docs continue to target testnet. See the [API introduction](/api-reference/introduction).
</Update>

<Update label="June 25, 2026" description="testnet-v1.1.91">
  ## Updates

  **Minimum withdrawal size enforced.** [`POST /v1/withdraw`](/api-reference/exchange/submit-withdrawal) now rejects amounts below the collateral currency's minimum with `400` — e.g. `validation error on field 'amount': must be at least 1000000000 quote quantums` (1e9 quote quantums = \$1). Amounts must also be exactly representable in collateral base units.

  **`compliance` address section now conditional.** [`GET /v1/compliance`](/api-reference/public/get-compliance-status) returns the `address` screening section only when the `?address=` query param is supplied; `geo` is always present. `address` is no longer a required response field.

  **Spot price & candle WebSocket payloads documented.** The `api-meta` `prices` and `candles` WebSocket channels now have published payload schemas (`SpotPrices` / `SpotPrice` and `SpotCandlesSubscribed` / `SpotCandlesChannelData`) covering both the subscribe snapshot and the per-tick `channel_data` frames.
</Update>

<Update label="June 24, 2026" description="testnet-v1.1.90">
  ## Breaking changes

  **Order time-in-force rules tightened.** New per-order-type `timeInForce` constraints, enforced at request validation:

  * **Every order must include `goodTilTime`** (epoch microseconds) set **at least one month in the future** — now required even for `IOC` orders, which previously ignored it. A missing value is rejected with `validation error on field 'goodTilTime': is required`.
  * **`MARKET` orders must use `IOC`.** `GTT`, `FOK`, and `ALO` are rejected with `validation error on field 'timeInForce': must be IOC for MARKET orders`.
  * **TPSL orders:** `LIMIT` TPSL legs must use `GTT`; `MARKET` TPSL legs must use `IOC`. (TPSL legs must also be `reduceOnly`, and are placed via `batchPlaceOrders` groupings.)
</Update>

<Update label="June 24, 2026" description="testnet-v1.1.89">
  ## New features

  **Server time.** [`GET /v1/time`](/api-reference/utility/get-current-server-time) returns the current server time — useful for aligning the nanosecond signing timestamp with the gateway's ±30s drift window.
</Update>

<Update label="June 22, 2026" description="testnet-v1.1.82">
  ## Breaking changes

  **Order signing moved to the ordersign typed canonical payload.** `placeOrder`, `cancelOrder`, and `modifyOrder` — and each element of `batchPlaceOrders` / `batchCancelOrders` — now sign a compact, key-sorted JSON payload built from the parsed request: the payload object **is** the Ed25519 message, with no `timestamp + action` prefix. The timestamp is carried as the `ct` field (it must equal `X-Timestamp`), and price/size are signed as integer ticks/quantums derived from the market's `tickSize` / `stepSize`. The previous `X-Timestamp + action + canonicalJSON(body)` scheme is now rejected with `401` for these endpoints. `cancelAllOrders`, `setLeverage`, and WebSocket authentication keep the legacy message. See [Authentication](/api-reference/authentication).

  **`GTC` replaced by `GTT`.** The `timeInForce` enum is now `GTT`, `IOC`, `FOK`, `ALO`. Resting orders (`GTT`, `ALO`) require `goodTilTime` (epoch microseconds) set **at least one month in the future** at the time the order is processed; nearer or missing values are rejected.

  **Withdrawals now use EIP-712 typed data.** [`POST /v1/withdraw`](/api-reference/exchange/submit-withdrawal) authenticates with an `eth_signTypedData_v4` signature over a `Withdraw` typed payload (domain and types in the endpoint reference) instead of the previous SHA-256 ECDSA canonical message.

  **Market orders require a protective price bound.** A `MARKET` order's `price` must be within **10%** of the current mark price (TPSL market orders: within 10% of the trigger price), or the order is rejected. With this bound, market orders behave like marketable limit orders.

  ## Updates

  **New order rejection reason.** `PRICE_WILL_EXCEED_MAXIMUM_OUTSIDE_RTH_TRADING_BOUND` is added to the `RejectionReason` set delivered on the `orders` WebSocket channel — emitted when a resting order's price would breach the maximum off-hours trading bound once the current regular-trading-hours session ends.
</Update>

<Update label="June 19, 2026" description="Endpoint migration">
  ## Breaking changes

  **API base URLs moved to `api.testnet.arcus.xyz`.** REST is now `https://api.testnet.arcus.xyz` and WebSocket `wss://api.testnet.arcus.xyz/v1/ws/`. The previous hostnames are being retired — update any saved base URLs, SDK configs, and clients at your earliest convenience to avoid disruption. Paths and payloads are unchanged. See the [API introduction](/api-reference/introduction).
</Update>

<Update label="June 19, 2026" description="testnet-v1.1.79">
  ## New features

  **Spot market overview REST endpoint.** [`GET /v1/api-meta/spot/overview`](/api-reference/marketmetadata/get-spot-market-overview) returns the curated spot market universe in source order, with each entry augmented by `Market Cap` and `logo_url` from the latest stored market metadata profile when available. Public — no `X-API-Key` or signature required.
</Update>

<Update label="June 17, 2026" description="testnet-v1.1.78">
  ## Breaking changes

  **Candles pagination replaced.** [`GET /v1/candles`](/api-reference/public/get-ohlcv-candles) no longer accepts `limit`. A request must now pass `to` — the upper bound of the window as a Unix **microsecond** timestamp (seconds- or milliseconds-scale values are rejected) — and may scope the lower bound with either `countback` (number of closed bars counting back from `to`) or `from` (a microsecond lower bound); `from` and `countback` are mutually exclusive. A request without `to` now returns `400`.

  **`volume30d` renamed to `rollingVolume`.** [`GET /v1/account/stats`](/api-reference/public/get-account-stats) and the affiliate commission and claim schemas now report notional fill volume under `rollingVolume`, measured over the fee-tier rolling window rather than a fixed trailing 30 days. Update any client that reads `volume30d`.

  ## Updates

  **New order rejection reasons.** The `RejectionReason` set delivered on the `orders` WebSocket channel adds `OPEN_ORDER_CAP_EXCEEDED`, `ORDER_NOT_FOUND`, `ORDER_NOT_FOUND_FOR_MODIFY`, `MODIFY_CHANGED_IMMUTABLE_FIELD`, `MODIFY_ZERO_SIZE`, and `ORDER_WILL_TAKE_LIQUIDITY_DURING_MARKET_HALT`.

  **Market asset name in metadata.** Market metadata responses now include `fullAssetName` (e.g. `Bitcoin`) when a canonical name is configured for the market.
</Update>

<Update label="June 16, 2026" description="testnet-v1.1.75">
  ## Breaking changes

  **Unified request signing.** REST and WebSocket now share one signing message: `X-Timestamp + action + canonicalJSON(body)`, where `action` is the canonical operation name — the REST path's final segment or the WebSocket request `type` (e.g. `placeOrder`, `cancelOrder`). The HTTP method and the `/ws/v1/` path prefix are no longer part of the signed message; re-sign with the new message before sending or the request is rejected with `401 invalid signature`. Batch methods sign each element over its singular action (e.g. `placeOrder` for each order in `batchPlaceOrders`) with one shared timestamp. The cutover also invalidates API keys registered before it — re-register via `POST /v1/createApiKey` (EIP-191 registration is unchanged). See [Authentication](/api-reference/authentication).
</Update>

<Update label="June 11, 2026" description="testnet-v1.1.74">
  ## Breaking changes

  **Protected requests now require nanosecond timestamps.** The signing timestamp — `X-Timestamp` for REST, `timestamp` for WebSocket order methods — must now be Unix time in **nanoseconds** as a decimal string (e.g. `1713825891591000000`), not milliseconds. Millisecond or second epochs are rejected with `401 Unauthorized`. Update any client that builds the signing message before re-signing. See [Authentication](/api-reference/authentication).

  ## Updates

  **User-facing timestamps are now microseconds.** Response time fields — candle `openTime`, funding payment times, and order placement/update times — are emitted in Unix microseconds for consistent precision across the API.
</Update>

<Update label="June 11, 2026" description="testnet-v1.1.70">
  ## New features

  **Market overview REST endpoint.** [`GET /v1/api-meta/overview`](/api-reference/marketmetadata/get-market-overview) returns a consolidated per-market overview keyed by base asset, so clients can fetch headline market data in a single call.

  **Volume leaderboard REST endpoint.** [`GET /v1/affiliate/volumeleaderboard`](/api-reference/public/get-the-all-traders-leaderboard) returns the top addresses ranked by signed-notional fill volume over a rolling window — `all`, `30d`, or `24h` (default `30d`).

  **Referral commission rate schedule.** [`GET /v1/commissionrates`](/api-reference/public/get-referral-commission-rate-schedule) returns the referral commission rate schedule used to compute affiliate payouts on each fill.
</Update>

<Update label="June 8, 2026" description="testnet-v1.1.69">
  ## New features

  **Push notification device tokens.** Register an Expo push token for the calling wallet with [`POST /v1/api-meta/notifications/tokens`](/api-reference/notifications/register-an-expo-push-token) so the notifications consumer can deliver a push when a matching event (resting fill, liquidation, TP/SL trigger) lands, and remove it with [`DELETE /v1/api-meta/notifications/tokens`](/api-reference/notifications/unregister-an-expo-push-token).
</Update>

<Update label="June 5, 2026" description="testnet-v1.1.65">
  ## New features

  **Rate-limit usage REST endpoint.** [`GET /v1/rateLimit`](/api-reference/public/get-current-rate-limit-usage) returns the state of both per-subaccount throttle pools (order and cancel), so clients can self-pace and see which limit is currently constraining them.

  **Withdrawals REST endpoint.** [`POST /v1/withdraw`](/api-reference/exchange/submit-withdrawal) submits a withdrawal of collateral to the chain.

  **Market metadata REST endpoints.** [`GET /v1/api-meta/markets`](/api-reference/marketmetadata/get-market-metadata) returns curated reference data — company profile, branding, headline financials, and TradingView chart identifiers — for one or all markets. Branding icons and market capitalizations are served by [`GET /v1/api-meta/overview`](/api-reference/marketmetadata/get-market-overview), which folds in what were briefly separate `icons` / `marketCaps` projections.

  **Notifications REST endpoints.** List the most recent notifications for an address (newest-first) with [`GET /v1/api-meta/notifications`](/api-reference/notifications/list-notifications-for-an-address), and mark them read with [`PATCH /v1/api-meta/notifications:markSeen`](/api-reference/notifications/mark-notifications-as-seen) — either an explicit list of `(created_at_ns, notification_id)` pairs, or the most recent `limit` rows for the wallet via `all=true`.

  **Referral code availability.** [`GET /v1/affiliate/codeAvailable`](/api-reference/referral/check-whether-a-referral-code-is-available) returns `{ code, available }` for a single referral code string.
</Update>

<Update label="May 27, 2026" description="testnet-v1.1.56">
  ## New features

  **Fee tier table REST endpoint.** [`GET /v1/feetiers`](/api-reference/public/get-fee-tier-table) returns the full fee tier table, sorted ascending by level (`0=Base` through `4=Platinum`) — the maker/taker fee BPS for each tier and the 30-day notional volume threshold required to reach it.

  **Exchange attribute updates WebSocket channel.** Subscribe to [`exchangeAttributeUpdates`](/api-reference/channels#exchangeattributeupdates) for exchange-wide state, discriminated by entry `type`. The current type, `feeTierConfig`, sends the full fee tier table on subscribe and a fresh replacement whenever an operator updates it — the streaming counterpart to `GET /v1/feetiers`.
</Update>

<Update label="May 27, 2026" description="testnet-v1.1.54">
  ## New features

  **Account attribute updates WebSocket channel.** Subscribe to [`accountAttributeUpdates`](/api-reference/channels#accountattributeupdates) for live per-account state — effective leverage per market and the account's current trading fee tier — discriminated by entry `type` (`"leverage"` or `"feeTier"`). On subscribe the server sends one leverage entry per market plus, when available, one fee tier entry; updates stream a single-entry delta for whichever attribute changed.

  **Leverages REST endpoint.** [`GET /v1/leverages`](/api-reference/public/get-leverage-for-an-account-across-all-markets) returns the effective leverage for `(address, accountIndex)` across every market, sorted by ascending `marketId`. Each entry reflects the user's override (set via [`POST /v1/setLeverage`](/api-reference/exchange/set-leverage-for-a-market)) when one exists, otherwise the market default.

  **Account stats REST endpoint.** [`GET /v1/account/stats`](/api-reference/public/get-account-stats) returns 30-day rolling notional fill volume and the current trading fee tier (level + BPS) for any Ethereum address.

  ## Updates

  **Affiliate endpoints moved.** All `/v1/api/affiliate/*` paths are now under [`/v1/affiliate/*`](/api-reference/referral/get-affiliate-info) — the legacy `/api/` segment has been dropped. Update any clients that hard-coded the old prefix. Operation IDs and request/response schemas are unchanged.
</Update>

<Update label="May 19, 2026" description="testnet-v1.1.47">
  ## New features

  **Trades REST endpoints.** Query recent public trades for a market with [`GET /v1/trades`](/api-reference/public/get-recent-public-trades), or fetch a single trade by ID with [`GET /v1/trade/{tradeId}`](/api-reference/public/get-a-single-trade-by-id).

  **Funding payments — REST and WebSocket.** Track per-account funding history with [`GET /v1/funding`](/api-reference/public/get-funding-payments) and per-market rates with [`GET /v1/fundingRates`](/api-reference/public/get-market-funding-rates). Stream live funding payments over the new [`funding`](/api-reference/channels#funding) WebSocket channel — snapshot of the 100 most recent payments on subscribe, then one event per `(market, account)` at each funding time. Positive `payment` = received, negative = paid.

  **Portfolio history.** [`GET /v1/portfolio`](/api-reference/public/get-portfolio-history) returns account equity, PnL, and value-over-time history for charting.

  **Positions REST endpoint.** [`GET /v1/positions`](/api-reference/public/get-positions) returns the current open positions for an account — the REST counterpart to the existing `positions` WebSocket channel.

  **Cancel-all and set-leverage.** [`POST /v1/cancelAllOrders`](/api-reference/exchange/cancel-all-open-orders) cancels every open order for an account in one call; [`POST /v1/setLeverage`](/api-reference/exchange/set-leverage-for-a-market) updates per-market leverage.

  **Account transfer updates.** [`GET /v1/accountTransferUpdates`](/api-reference/public/get-account-transfer-updates) returns deposit/withdrawal history with cursor pagination.

  **User preferences.** Persist client-side UI settings server-side via [`/v1/api-meta/userPreferences`](/api-reference/userpreferences/get-user-preferences).

  **Referral program.** Twelve new endpoints under [`/v1/api/affiliate/*`](/api-reference/referral/get-affiliate-info) cover the full affiliate lifecycle — create and revoke referral codes, register affiliates, view referees and leaderboard, track commissions and kickbacks, and claim rewards.
</Update>

<Update label="May 11, 2026" description="Initial testnet release">
  ## New features

  **REST and WebSocket API now live on testnet.** Trade, stream market data, and manage accounts against `https://api.testnet.arcus.xyz` (REST) and `wss://api.testnet.arcus.xyz/v1/ws/` (WebSocket). Both APIs are non-custodial — register an Ed25519 API key against your Ethereum address and the server never sees a private key. See the [API introduction](/api-reference/introduction) to get started.

  **Real-time market data channels.** Subscribe to live updates over WebSocket:

  * [`l2Orderbook`](/api-reference/channels#l2orderbook) and [`l2OrderbookUpdates`](/api-reference/channels#l2orderbookupdates) — full snapshots every \~500 ms, or initial snapshot plus incremental updates (1–100 levels).
  * [`bbo`](/api-reference/channels#bbo) — best bid and offer at the top of book.
  * [`trades`](/api-reference/channels#trades) — live public trade stream.
  * [`markets`](/api-reference/channels#markets) — global market metadata with funding rate, oracle and index prices, and 24h volume.
  * [`oraclePrices`](/api-reference/channels#oracleprices) — per-market oracle prices from the on-chain Slinky aggregator.
  * [`candles`](/api-reference/channels#candles) — OHLCV across 13 timeframes from `1m` to `1w`, with up to 200-candle snapshots.

  **Account and order channels.** Track your account state and order lifecycle in real time with [`account`](/api-reference/channels#account), [`positions`](/api-reference/channels#positions), [`orders`](/api-reference/channels#orders), and [`userFills`](/api-reference/channels#userfills).

  **Order routing over WebSocket.** Place, cancel, modify, and batch orders directly over WebSocket. All order methods are asynchronous and return a `202 ACK` — observe lifecycle through the `orders` and `userFills` channels. See [Placing orders](/api-reference/websocket#placing-orders).

  **Ed25519 API keys with Ethereum-signed registration.** Generate an Ed25519 key pair, register it with an ECDSA signature from your master Ethereum address, and sign protected requests with a Unix-millisecond timestamp. Full instructions in [Authentication](/api-reference/authentication).

  ## Updates

  **Rebranded to Arcus.** The product is now Arcus across all user-facing surfaces, including the API spec and documentation.

  ## Known limitations

  * `batchModifyOrders` is not yet implemented and returns `501`.
  * `createApiKey` is REST-only; the WebSocket equivalent returns `501 NotImplemented`.
</Update>
