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

# List positions

> A subaccount's perpetual positions and margin accounts, read from chain at request time. Positions are public on chain, so no signature is required. Everything is in the cNGN-PERP orientation: prices in USDC per cNGN, sizes in cNGN, long means long cNGN and is a positive engine_position. positions holds one entry per perp market with a non-zero position; accounts one entry per enabled perp market whether or not a position is held. Both are [] rather than null when empty, and both are empty when the deployment serves no perp. Market prices and margin rates are cached for 10 seconds; the account's balances are read fresh on every request.

Returns a subaccount's perpetual positions and margin accounts, read from chain at request time.
Positions are public on chain, so no signature is required: pass the `subaccount_id` and read.

The response always has two arrays, each `[]` rather than `null` when empty:

* `positions` — one entry per perp market where the account holds a non-zero position.
* `accounts` — one entry per enabled perp market, whether or not the account holds a position: its
  cash and margin surpluses are what a ticket shows as available before the first trade.

Both are empty when this deployment serves no perp.

## Reading a position

Everything is in the cNGN-PERP orientation: prices in USDC per cNGN, sizes in cNGN, and long means
long cNGN.

* `engine_position` is the signed cNGN balance of the perp on chain, as a decimal string with up to
  18 places. Positive is a long.
* `ui_side` is `long` when `engine_position` is positive, `short` when negative. `ui_size` is its
  magnitude in cNGN and `ui_notional_usdc` that size valued at the index, both to 6 decimal places.
* `mark_price_ui` and `index_price_ui` are the market's mark and index to 10 decimal places, the
  same values as the `perp` block on [`GET /v1/markets`](/api-reference/endpoint/get).
* `unrealized_pnl` is the position's unsettled and unrealized cash on chain, in USDC, signed.
* `initial_margin_surplus` and `maintenance_margin_surplus` are the SRM's own figures for the
  account, in USDC. Below zero means the account is under that margin; a negative maintenance
  surplus means it can be liquidated.
* `liquidation_price_ui` is an estimate: the price in USDC per cNGN at which the maintenance surplus
  reaches zero if nothing else changes, for an account holding only this position. It is **omitted**
  when no positive price gets there — a long at 1x, for example.

## Reading an account

* `cash` is the account's balance in the perp's CashAsset, in USDC, signed.
* `initial_margin_surplus` and `maintenance_margin_surplus` are as above. For an account with no
  position the initial surplus is its cash.
* `collateral` lists each base asset the account has posted as margin: `symbol`, `asset_address`,
  `balance` in that asset, `value_usd` at the index and `margin_value_usd`, the share the SRM credits
  after its `margin_factor`. Empty when nothing is posted, or margin is cash only.

Decimal fields read from chain are strings with up to 18 decimal places and no trailing zeros.

## Example

A long of 137,400 cNGN with 40 USDC of margin, at a mark of 0.0007278:

```json theme={null}
{
  "positions": [
    {
      "market": "USDCcNGN-PERP",
      "subaccount_id": "42",
      "engine_position": "137400",
      "ui_side": "long",
      "ui_size": "137400",
      "ui_notional_usdc": "100.0272",
      "mark_price_ui": "0.0007278",
      "index_price_ui": "0.000728",
      "unrealized_pnl": "-0.02748",
      "initial_margin_surplus": "6.63045",
      "maintenance_margin_surplus": "19.96708",
      "liquidation_price_ui": "0.00054615"
    }
  ],
  "accounts": [
    {
      "market": "USDCcNGN-PERP",
      "subaccount_id": "42",
      "cash": "40",
      "initial_margin_surplus": "6.63045",
      "maintenance_margin_surplus": "19.96708",
      "collateral": []
    }
  ]
}
```

## Polling

The market's mark, index and margin rates are cached for 10 seconds server-side; the account's
balances and surpluses are read from chain on every request. The Numo app polls this endpoint every
15 seconds, which is ample: funding accrues continuously, so there is no settlement instant to catch.

## Errors

| Status | Error | Cause |
| - | - | - |
| `400` | `subaccount_id is required` | The query parameter is missing. |
| `400` | `subaccount_id must be a non-negative integer` | Not a base-10 unsigned integer. |
| `502` | `could not read positions from chain` | The RPC read of the position failed. Retry. |
| `502` | `could not read the account from chain` | The RPC read of the account's margin failed. Retry. |


## OpenAPI

````yaml GET /v1/positions
openapi: 3.1.0
info:
  title: Numo orderbook API
  description: >-
    REST endpoints exposed by Numo's markets-service and execution-service for
    dollar stablecoins. Real-time book, trades, and order streams are served
    over the WebSocket endpoint documented in the WebSocket streams reference.
  version: 1.0.0
servers:
  - url: https://api.numofx.com
    description: markets-service
  - url: https://executor.numofx.com
    description: execution-service
security: []
tags:
  - name: Markets service
  - name: Execution service
paths:
  /v1/positions:
    get:
      tags:
        - Markets service
      summary: List perp positions
      description: >-
        A subaccount's perpetual positions and margin accounts, read from chain
        at request time. Positions are public on chain, so no signature is
        required. Everything is in the cNGN-PERP orientation: prices in USDC per
        cNGN, sizes in cNGN, long means long cNGN and is a positive
        engine_position. positions holds one entry per perp market with a
        non-zero position; accounts one entry per enabled perp market whether or
        not a position is held. Both are [] rather than null when empty, and
        both are empty when the deployment serves no perp. Market prices and
        margin rates are cached for 10 seconds; the account's balances are read
        fresh on every request.
      operationId: listPositions
      parameters:
        - name: subaccount_id
          in: query
          required: true
          schema:
            type: string
          description: Base-10 subaccount id, a non-negative integer.
      responses:
        '200':
          description: The account's perp positions and margin accounts
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PositionsResponse'
        '400':
          description: subaccount_id missing or not a non-negative integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '502':
          description: The position or account could not be read from chain. Retry.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    PositionsResponse:
      type: object
      required:
        - positions
        - accounts
      properties:
        positions:
          type: array
          description: >-
            One entry per perp market where the account holds a non-zero
            position. Empty array, never null.
          items:
            $ref: '#/components/schemas/PerpPosition'
        accounts:
          type: array
          description: >-
            One entry per enabled perp market, whether or not a position is
            held. Empty array, never null.
          items:
            $ref: '#/components/schemas/PerpAccount'
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
    PerpPosition:
      type: object
      description: >-
        A perp position in the cNGN-PERP orientation. Decimal fields are strings
        without trailing zeros.
      required:
        - market
        - subaccount_id
        - engine_position
        - ui_side
        - ui_size
        - ui_notional_usdc
        - mark_price_ui
        - index_price_ui
        - unrealized_pnl
        - initial_margin_surplus
        - maintenance_margin_surplus
      properties:
        market:
          type: string
          example: USDCcNGN-PERP
        subaccount_id:
          type: string
          example: '42'
        engine_position:
          type: string
          description: >-
            The signed cNGN balance of the perp on chain, up to 18 decimal
            places. Positive is a long.
          example: '137400'
        ui_side:
          type: string
          enum:
            - long
            - short
          description: >-
            long when engine_position is positive, short when negative. A long
            is long cNGN.
        ui_size:
          type: string
          description: '|engine_position| in cNGN, to 6 decimal places.'
          example: '137400'
        ui_notional_usdc:
          type: string
          description: ui_size valued at the index, in USDC, to 6 decimal places.
          example: '100.0272'
        mark_price_ui:
          type: string
          description: Mark price in USDC per cNGN to 10 decimal places.
          example: '0.0007278'
        index_price_ui:
          type: string
          description: Index price in USDC per cNGN to 10 decimal places.
          example: '0.000728'
        unrealized_pnl:
          type: string
          description: >-
            The position's unsettled and unrealized cash on chain, in USDC,
            signed, up to 18 decimal places.
          example: '-0.02748'
        initial_margin_surplus:
          type: string
          description: >-
            The SRM's initial margin surplus for the account, in USDC, signed.
            Below zero means under initial margin.
          example: '6.63045'
        maintenance_margin_surplus:
          type: string
          description: >-
            The SRM's maintenance margin surplus for the account, in USDC,
            signed. Below zero means liquidatable.
          example: '19.96708'
        liquidation_price_ui:
          type: string
          description: >-
            Estimated price in USDC per cNGN at which the maintenance surplus
            reaches zero if nothing else changes, for an account holding only
            this position, to 10 decimal places. Omitted when no positive price
            gets there (a long at 1x, for example).
          example: '0.00054615'
    PerpAccount:
      type: object
      description: >-
        The account's margin on a perp stack, whether or not it holds a
        position.
      required:
        - market
        - subaccount_id
        - cash
        - initial_margin_surplus
        - maintenance_margin_surplus
        - collateral
      properties:
        market:
          type: string
          example: USDCcNGN-PERP
        subaccount_id:
          type: string
          example: '42'
        cash:
          type: string
          description: >-
            Balance in the perp's CashAsset, in USDC, signed, up to 18 decimal
            places.
          example: '40'
        initial_margin_surplus:
          type: string
          description: >-
            The SRM's initial margin surplus, in USDC. For an account with no
            position, its cash.
          example: '6.63045'
        maintenance_margin_surplus:
          type: string
          description: The SRM's maintenance margin surplus, in USDC.
          example: '19.96708'
        collateral:
          type: array
          description: >-
            Each base asset the account has posted as margin. Empty array when
            none is held, or margin is cash only.
          items:
            $ref: '#/components/schemas/PerpAccountCollateral'
    PerpAccountCollateral:
      type: object
      required:
        - symbol
        - asset_address
        - balance
        - value_usd
        - margin_value_usd
      properties:
        symbol:
          type: string
          example: cNGN
        asset_address:
          type: string
          description: The escrow holding the collateral.
        balance:
          type: string
          description: Posted balance in the asset, up to 18 decimal places.
        value_usd:
          type: string
          description: The balance at the index, in USDC, up to 18 decimal places.
        margin_value_usd:
          type: string
          description: >-
            value_usd x the asset's margin_factor: what the SRM credits as
            margin, in USDC.

````

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