Skip to main content
GET
cURL

Authorizations

X-Monaco-Signature
string
header
required

Ed25519 session-key request signing. Every authenticated request carries three headers: X-Monaco-PublicKey (64-char lowercase-hex session public key), X-Monaco-Timestamp (Unix milliseconds, within 30s of server time), and X-Monaco-Signature (hex ed25519 signature). The signature is over METHOD\npath?query\ntimestamp_ms\nSHA256_hex(body), where the body hash is the SHA-256 of the empty byte string when there is no body. Obtain the session keypair from POST /api/v1/auth/challenge followed by POST /api/v1/auth/verify.

Path Parameters

positionId
string
default:2b1a5f9c-0000-4000-8000-000000000002
required

Response

OK

positionId
string | null
marginAccountId
string | null

Margin account UUID for the isolated bucket that owns this position.

tradingPairId
string<uuid> | null
side
string | null
size
string | null

Open rows: current absolute position quantity. Terminal rows (CLOSED/LIQUIDATED/EXPIRED): total quantity closed over the position's life, summed from its reducing executions when available.

entryPrice
string | null
markPrice
string | null
indexPrice
string | null
unrealizedPnl
string | null
realizedPnl
string | null
isolatedMargin
string | null

Open ISOLATED rows: principal committed to the filled position, adjusted by settled realized PnL, fees and funding, clamped at zero. Collateral allocated to unfilled orders is excluded. This is the unrealized-return denominator and the same backing used by isolated liquidation. Placing, cancelling or resizing an unfilled order does not add position backing. A price gap can pass the backing before asynchronous liquidation occurs. Live and persisted reads use the same position-principal basis. Open CROSS rows: the position's posted margin. Terminal rows: total initial margin allocated across the position's reducing executions when available, used as the basis for lifetime realized return.

leverage
string | null
maintenanceMarginRequired
string | null

Maintenance margin required by this position at mark_price using the market maintenance-margin rate. Zero when the position has no open exposure.

initialMarginRequired
string | null

Initial margin required by this position at mark_price, honoring both its effective leverage and the market initial-margin floor. Zero when the position has no open exposure.

liquidationPrice
string | null

Liquidation mark-price threshold. In ISOLATED mode, this is the position/risk-bucket threshold. In CROSS mode, it is conditional: it varies only this position's mark while all other marks in the cross risk bucket remain unchanged. Other position marks, funding, realized PnL, fees/reserves, and collateral can change it. Treat an absent or blank value as unavailable, never as zero.

status
string | null
updatedAt
string | null

RFC 3339 instant at which this position was last MUTATED — a fill, collateral transfer, funding settlement or close — as the producer that owns the position recorded it. It is NOT the instant the response was built: polling an unchanged position returns the same value, and an oracle reprice does not move it. For an OPEN position every surface reports the same instant — the list, the detail read, the risk read, the WebSocket positions snapshot, and the live position_update frames.

Two cases come from the persistence clock instead and differ from the matching engine's by the persistence lag: a TERMINAL row (the live position_update frame carries the engine's close instant, this field carries the stored one), and any position read after a matching-engine restart. Accurate to that lag, not to the microsecond.

A third case is not lag-bounded: an OPEN row read while the matching engine is unreachable falls back to the row's own lifecycle columns (close, then last funding, then open), so a position filled repeatedly since it opened reports its opening instant until funding settles. The live position_update frame is unaffected.

Display metadata. version is the reconciliation key; ordering position state by this field is never correct.

riskBucketId
string | null
marginMode
string | null
netRealizedPnl
string | null

Lifetime realized PnL net of trading fees and funding. Terminal rows only; absent when the position's reducing executions are unavailable.

realizedRoe
string | null

Lifetime realized return on the total allocated initial margin, as a percentage, computed from NET realized PnL (after trading fees and funding). The denominator is initial margin only: fees and funding are costs rather than posted collateral, and funding is signed, so folding it into the denominator could drive it to zero or negative. Terminal rows only; absent when unavailable, including when the position's reducing executions do not account for its whole lifetime.

exitPrice
string | null

Volume-weighted average price across the position's reducing executions. Positions closed in several fills exit at this price, not at the final fill or the mark at close. Terminal rows only; absent when the position's reducing executions do not account for its whole lifetime.

fundingPaid
string | null

Lifetime funding paid (signed; negative means received), summed over the position's reducing executions. Terminal rows only; absent when the position's reducing executions do not account for its whole lifetime.

feesPaid
string | null

Trading fees paid on the position's reducing executions (signed; negative means rebated). Closing-side fees only — fees on opening fills are not included. Terminal rows only; absent when the position's reducing executions do not account for its whole lifetime.

cumFees
string | null

Total lifetime trading fees for the position: opening-fill fees (from the PnL cost-basis engine) plus every reducing execution's fees — decreases, close, and any liquidation penalty. Signed; negative means net rebated, inclusive of the application-fee component. Unlike the closing-side reducing-execution fee field above, which omits opening fills, this is the whole-life figure, on open and terminal rows alike. Null when the opening-fill fees are unavailable — before the position's first PnL sample flushes, after its samples age out of PnL retention, or for positions predating the PnL service — rather than an understated partial.

version
integer<int64> | null

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.

Required range: x >= 0
Example:

918342