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

# Positions Stream

> Open positions with mark price, margin, and PnL.

This stream is available on the `optionsPositions` subscription. It provides your open option positions with mark price, margin, and PnL.

#### Snapshot vs. Delta

The `emitOptionsPositions` request returns a snapshot via `optionsPositions`. Once subscribed, `optionsPositionsDelta` messages carry changed positions in the same shape. A delta has no `clientRequestId` — that is what distinguishes the live push from a snapshot response.

#### Closed Positions Arrive as `flat`

When a position is closed, the delta reports it with `side` `flat` and `qty` `0`. This is the only message that tells you the position is gone.

<Warning>
  Handle `flat` explicitly: **remove** the position from your book when you receive it. A client that only switches on `long` and `short` will ignore the message and keep showing a position it no longer holds — no further delta and no snapshot will ever correct it, because the snapshot omits closed positions entirely.
</Warning>

`flat` only ever appears on a delta. The `emitOptionsPositions` snapshot returns open positions only, so a closed position is simply absent from it.

See [Position Metrics](/latest/options/formulas/position-metrics) for how `value`, `notionalValue`, `unrealizedPnl`, and `breakEvenPrice` are derived.


## AsyncAPI

````yaml latest/options/asyncapi/options-ws.yaml positionsStream
id: positionsStream
title: Positions Stream
description: >
  Available on the `optionsPositions` subscription. Your open option positions
  with mark price, margin, and PnL.
servers:
  - id: sandbox
    protocol: wss
    host: ws.sandbox.rails.xyz
    bindings: []
    variables: []
address: >-
  ?product=options&market={market}&expiration={expiration}&strike={strike}&type={type}&subscriptions=optionsPositions
parameters:
  - id: market
    jsonSchema:
      type: string
      description: A specific market (e.g. `BTC-USDT`) or `ALL`.
      default: BTC-USDT
    description: A specific market (e.g. `BTC-USDT`) or `ALL`.
    type: string
    required: true
    deprecated: false
  - id: expiration
    jsonSchema:
      type: string
      description: >-
        Contract expiration, e.g. `24JUN26`. Requires `market`; omit to match
        every expiration.
      default: 24JUN26
    description: >-
      Contract expiration, e.g. `24JUN26`. Requires `market`; omit to match
      every expiration.
    type: string
    required: true
    deprecated: false
  - id: strike
    jsonSchema:
      type: string
      description: >-
        Strike price, e.g. `62000`. Requires `expiration`; omit to match every
        strike.
      default: '62000'
    description: >-
      Strike price, e.g. `62000`. Requires `expiration`; omit to match every
      strike.
    type: string
    required: true
    deprecated: false
  - id: type
    jsonSchema:
      type: string
      description: '`C` (call) or `P` (put). Requires `strike`; omit to match both.'
      default: C
    description: '`C` (call) or `P` (put). Requires `strike`; omit to match both.'
    type: string
    required: true
    deprecated: false
bindings: []
operations:
  - &ref_2
    id: emitOptionsPositions
    title: Emit options positions
    description: Request a snapshot of your open positions.
    type: receive
    messages:
      - &ref_5
        id: emitOptionsPositionsRequest
        contentType: application/json
        payload:
          - name: Emit Options Positions
            type: object
            properties:
              - name: message
                type: string
                description: Always `emitOptionsPositions`.
                required: true
              - name: content
                type: object
                required: false
                properties:
                  - name: clientRequestId
                    type: string
                    description: Client-generated UUID for correlation
                    required: false
                  - name: market
                    type: string
                    description: >-
                      A contract name to filter, or `ALL` for every position.
                      Defaults to `ALL`
                    required: false
                  - name: pageSize
                    type: integer
                    description: >-
                      Page size, `1`–`200`. Omit it to receive every position in
                      one message
                    required: false
                  - name: pageToken
                    type: string
                    description: Cursor for the next page. Requires `pageSize`
                    required: false
        headers: []
        jsonPayloadSchema:
          type: object
          properties:
            message:
              type: string
              description: Always `emitOptionsPositions`.
              x-parser-schema-id: <anonymous-schema-359>
            content:
              type: object
              properties:
                clientRequestId:
                  type: string
                  format: uuid
                  description: Client-generated UUID for correlation
                  x-parser-schema-id: <anonymous-schema-361>
                market:
                  type: string
                  description: >-
                    A contract name to filter, or `ALL` for every position.
                    Defaults to `ALL`
                  x-parser-schema-id: <anonymous-schema-362>
                pageSize:
                  type: integer
                  minimum: 1
                  maximum: 200
                  description: >-
                    Page size, `1`–`200`. Omit it to receive every position in
                    one message
                  x-parser-schema-id: <anonymous-schema-363>
                pageToken:
                  type: string
                  description: Cursor for the next page. Requires `pageSize`
                  x-parser-schema-id: <anonymous-schema-364>
              x-parser-schema-id: <anonymous-schema-360>
          required:
            - message
          x-parser-schema-id: <anonymous-schema-358>
        title: Emit Options Positions
        example: |-
          {
            "message": "emitOptionsPositions",
            "content": {
              "clientRequestId": "b8c56794-c7f8-467d-b331-be8c765a5378",
              "market": "BTC-10JUL26-55000-C"
            }
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: emitOptionsPositionsRequest
    bindings: []
    extensions: &ref_0
      - id: x-parser-unique-object-id
        value: positionsStream
  - &ref_3
    id: optionsPositionsSnapshot
    title: Options positions snapshot
    description: Response to `emitOptionsPositions`.
    type: send
    messages:
      - &ref_6
        id: optionsPositionsResponse
        contentType: application/json
        payload:
          - name: Positions Snapshot
            description: Response to `emitOptionsPositions`.
            type: object
            properties:
              - name: resultType
                type: string
                description: Always `optionsPositions`.
                required: true
              - name: market
                type: string
                description: Contract name, or `ALL`
                required: true
              - name: data
                type: object
                required: true
                properties:
                  - name: positions
                    type: array
                    description: Your open positions
                    required: true
                    properties:
                      - name: contract
                        type: string
                        description: Contract name
                        required: true
                      - name: side
                        type: string
                        description: >
                          Position side. `flat` appears only on deltas, when a
                          position closes — remove the position from your book
                          on receiving it; the snapshot omits closed positions
                          entirely
                        enumValues:
                          - long
                          - short
                          - flat
                        required: true
                      - name: optionType
                        type: string
                        description: >-
                          Option type — `C` (call) or `P` (put), matching the
                          contract name
                        enumValues:
                          - C
                          - P
                        required: true
                      - name: qty
                        type: string
                        description: >
                          Signed position quantity — negative for a short.
                          `side` carries the same direction
                        required: true
                      - name: value
                        type: string
                        description: |
                          Position value at entry, signed (negative for a short)
                        required: true
                      - name: fees
                        type: string
                        description: >
                          Fees actually charged to open the current position.
                          Reducing the position reduces `fees` in the same
                          proportion, so it always covers only the contracts
                          still held; `0` once the position closes
                        required: true
                      - name: entryPrice
                        type: string
                        description: Average entry price
                        required: true
                      - name: markPrice
                        type: string
                        description: Current mark price
                        required: true
                      - name: markIV
                        type: string
                        description: Mark implied volatility
                        required: true
                      - name: underlyingPrice
                        type: string
                        description: Underlying index price
                        required: true
                      - name: breakEvenPrice
                        type: string
                        description: >-
                          Break-even price at expiry, net of premium and opening
                          fees per contract
                        required: true
                      - name: initialMargin
                        type: string
                        description: Initial margin (short positions; `0` for long)
                        required: true
                      - name: realizedPnl
                        type: string
                        description: Realized PnL
                        required: true
                      - name: unrealizedPnl
                        type: string
                        description: Unrealized PnL
                        required: true
                      - name: notionalValue
                        type: string
                        description: >-
                          Notional value of the position, signed (negative for
                          short positions); `0` when the mark price is
                          unavailable
                        required: true
                      - name: updatedAt
                        type: integer
                        description: Last update (ms since epoch)
                        required: true
                  - name: statusCode
                    type: integer
                    description: Always `200`.
                    required: true
                  - name: clientRequestId
                    type: string
                    description: Client-generated UUID for correlation
                    required: false
                  - name: nextPageToken
                    type: string
                    description: >
                      Cursor for the next page; absent on the last page, and
                      absent entirely when you emit without `pageSize`
                    required: false
        headers: []
        jsonPayloadSchema:
          type: object
          properties:
            resultType:
              type: string
              description: Always `optionsPositions`.
              x-parser-schema-id: <anonymous-schema-366>
            market:
              type: string
              description: Contract name, or `ALL`
              x-parser-schema-id: <anonymous-schema-367>
            data:
              type: object
              properties:
                positions:
                  type: array
                  description: Your open positions
                  items: &ref_1
                    type: object
                    properties:
                      contract:
                        type: string
                        description: Contract name
                        x-parser-schema-id: <anonymous-schema-370>
                      side:
                        type: string
                        enum:
                          - long
                          - short
                          - flat
                        description: >
                          Position side. `flat` appears only on deltas, when a
                          position closes — remove the position from your book
                          on receiving it; the snapshot omits closed positions
                          entirely
                        x-parser-schema-id: <anonymous-schema-371>
                      optionType:
                        type: string
                        enum:
                          - C
                          - P
                        description: >-
                          Option type — `C` (call) or `P` (put), matching the
                          contract name
                        x-parser-schema-id: <anonymous-schema-372>
                      qty:
                        type: string
                        description: >
                          Signed position quantity — negative for a short.
                          `side` carries the same direction
                        x-parser-schema-id: <anonymous-schema-373>
                      value:
                        type: string
                        description: |
                          Position value at entry, signed (negative for a short)
                        x-parser-schema-id: <anonymous-schema-374>
                      fees:
                        type: string
                        description: >
                          Fees actually charged to open the current position.
                          Reducing the position reduces `fees` in the same
                          proportion, so it always covers only the contracts
                          still held; `0` once the position closes
                        x-parser-schema-id: <anonymous-schema-375>
                      entryPrice:
                        type: string
                        description: Average entry price
                        x-parser-schema-id: <anonymous-schema-376>
                      markPrice:
                        type: string
                        description: Current mark price
                        x-parser-schema-id: <anonymous-schema-377>
                      markIV:
                        type: string
                        description: Mark implied volatility
                        x-parser-schema-id: <anonymous-schema-378>
                      underlyingPrice:
                        type: string
                        description: Underlying index price
                        x-parser-schema-id: <anonymous-schema-379>
                      breakEvenPrice:
                        type: string
                        description: >-
                          Break-even price at expiry, net of premium and opening
                          fees per contract
                        x-parser-schema-id: <anonymous-schema-380>
                      initialMargin:
                        type: string
                        description: Initial margin (short positions; `0` for long)
                        x-parser-schema-id: <anonymous-schema-381>
                      realizedPnl:
                        type: string
                        description: Realized PnL
                        x-parser-schema-id: <anonymous-schema-382>
                      unrealizedPnl:
                        type: string
                        description: Unrealized PnL
                        x-parser-schema-id: <anonymous-schema-383>
                      notionalValue:
                        type: string
                        description: >-
                          Notional value of the position, signed (negative for
                          short positions); `0` when the mark price is
                          unavailable
                        x-parser-schema-id: <anonymous-schema-384>
                      updatedAt:
                        type: integer
                        description: Last update (ms since epoch)
                        x-parser-schema-id: <anonymous-schema-385>
                    required:
                      - contract
                      - side
                      - optionType
                      - qty
                      - value
                      - fees
                      - entryPrice
                      - markPrice
                      - markIV
                      - underlyingPrice
                      - breakEvenPrice
                      - initialMargin
                      - realizedPnl
                      - unrealizedPnl
                      - notionalValue
                      - updatedAt
                    x-parser-schema-id: Position
                  x-parser-schema-id: <anonymous-schema-369>
                statusCode:
                  type: integer
                  description: Always `200`.
                  x-parser-schema-id: <anonymous-schema-386>
                clientRequestId:
                  type: string
                  description: Client-generated UUID for correlation
                  x-parser-schema-id: <anonymous-schema-387>
                nextPageToken:
                  type: string
                  description: >
                    Cursor for the next page; absent on the last page, and
                    absent entirely when you emit without `pageSize`
                  x-parser-schema-id: <anonymous-schema-388>
              required:
                - positions
                - statusCode
              x-parser-schema-id: <anonymous-schema-368>
          required:
            - resultType
            - market
            - data
          x-parser-schema-id: <anonymous-schema-365>
        title: Positions Snapshot
        description: Response to `emitOptionsPositions`.
        example: |-
          {
            "resultType": "optionsPositions",
            "market": "BTC-10JUL26-55000-C",
            "data": {
              "positions": [
                {
                  "contract": "BTC-10JUL26-55000-C",
                  "side": "long",
                  "optionType": "C",
                  "qty": "1",
                  "value": "6948.86",
                  "fees": "3.47443",
                  "entryPrice": "6948.86",
                  "markPrice": "7194.0717439",
                  "markIV": "0.490087689370473",
                  "underlyingPrice": "62142.5973392596",
                  "breakEvenPrice": "61952.33443",
                  "initialMargin": "0",
                  "realizedPnl": "0",
                  "unrealizedPnl": "245.2117439",
                  "notionalValue": "7194.0717439",
                  "updatedAt": 1783079880460
                }
              ],
              "statusCode": 200,
              "clientRequestId": "b8c56794-c7f8-467d-b331-be8c765a5378"
            }
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: optionsPositionsResponse
    bindings: []
    extensions: *ref_0
  - &ref_4
    id: optionsPositionsUpdate
    title: Options positions update
    description: Pushed whenever your positions change.
    type: send
    messages:
      - &ref_7
        id: optionsPositionsDelta
        contentType: application/json
        payload:
          - name: Position Delta
            description: >
              Pushed whenever your positions change; carries changed positions
              in the same shape as the snapshot. A delta has no
              `clientRequestId` — that is what distinguishes the live push from
              a snapshot response. A closed position arrives with `side` `flat`
              and `qty` `0`; this is the only message that tells you the
              position is gone.
            type: object
            properties:
              - name: resultType
                type: string
                description: Always `optionsPositionsDelta`.
                required: true
              - name: market
                type: string
                description: Contract name
                required: true
              - name: data
                type: object
                required: true
                properties:
                  - name: positions
                    type: array
                    description: Changed positions
                    required: true
                    properties:
                      - name: contract
                        type: string
                        description: Contract name
                        required: true
                      - name: side
                        type: string
                        description: >
                          Position side. `flat` appears only on deltas, when a
                          position closes — remove the position from your book
                          on receiving it; the snapshot omits closed positions
                          entirely
                        enumValues:
                          - long
                          - short
                          - flat
                        required: true
                      - name: optionType
                        type: string
                        description: >-
                          Option type — `C` (call) or `P` (put), matching the
                          contract name
                        enumValues:
                          - C
                          - P
                        required: true
                      - name: qty
                        type: string
                        description: >
                          Signed position quantity — negative for a short.
                          `side` carries the same direction
                        required: true
                      - name: value
                        type: string
                        description: |
                          Position value at entry, signed (negative for a short)
                        required: true
                      - name: fees
                        type: string
                        description: >
                          Fees actually charged to open the current position.
                          Reducing the position reduces `fees` in the same
                          proportion, so it always covers only the contracts
                          still held; `0` once the position closes
                        required: true
                      - name: entryPrice
                        type: string
                        description: Average entry price
                        required: true
                      - name: markPrice
                        type: string
                        description: Current mark price
                        required: true
                      - name: markIV
                        type: string
                        description: Mark implied volatility
                        required: true
                      - name: underlyingPrice
                        type: string
                        description: Underlying index price
                        required: true
                      - name: breakEvenPrice
                        type: string
                        description: >-
                          Break-even price at expiry, net of premium and opening
                          fees per contract
                        required: true
                      - name: initialMargin
                        type: string
                        description: Initial margin (short positions; `0` for long)
                        required: true
                      - name: realizedPnl
                        type: string
                        description: Realized PnL
                        required: true
                      - name: unrealizedPnl
                        type: string
                        description: Unrealized PnL
                        required: true
                      - name: notionalValue
                        type: string
                        description: >-
                          Notional value of the position, signed (negative for
                          short positions); `0` when the mark price is
                          unavailable
                        required: true
                      - name: updatedAt
                        type: integer
                        description: Last update (ms since epoch)
                        required: true
                  - name: statusCode
                    type: integer
                    description: Always `200`.
                    required: true
        headers: []
        jsonPayloadSchema:
          type: object
          properties:
            resultType:
              type: string
              description: Always `optionsPositionsDelta`.
              x-parser-schema-id: <anonymous-schema-390>
            market:
              type: string
              description: Contract name
              x-parser-schema-id: <anonymous-schema-391>
            data:
              type: object
              properties:
                positions:
                  type: array
                  description: Changed positions
                  items: *ref_1
                  x-parser-schema-id: <anonymous-schema-393>
                statusCode:
                  type: integer
                  description: Always `200`.
                  x-parser-schema-id: <anonymous-schema-394>
              required:
                - positions
                - statusCode
              x-parser-schema-id: <anonymous-schema-392>
          required:
            - resultType
            - market
            - data
          x-parser-schema-id: <anonymous-schema-389>
        title: Position Delta
        description: >
          Pushed whenever your positions change; carries changed positions in
          the same shape as the snapshot. A delta has no `clientRequestId` —
          that is what distinguishes the live push from a snapshot response. A
          closed position arrives with `side` `flat` and `qty` `0`; this is the
          only message that tells you the position is gone.
        example: |-
          {
            "resultType": "optionsPositionsDelta",
            "market": "BTC-10JUL26-55000-C",
            "data": {
              "positions": [
                {
                  "contract": "BTC-10JUL26-55000-C",
                  "side": "long",
                  "optionType": "C",
                  "qty": "1",
                  "value": "6948.86",
                  "fees": "3.47443",
                  "entryPrice": "6948.86",
                  "markPrice": "7250.5",
                  "markIV": "0.4915",
                  "underlyingPrice": "62200.1",
                  "breakEvenPrice": "61952.33443",
                  "initialMargin": "0",
                  "realizedPnl": "0",
                  "unrealizedPnl": "301.64",
                  "notionalValue": "7250.5",
                  "updatedAt": 1783351516417
                }
              ],
              "statusCode": 200
            }
          }
        bindings: []
        extensions:
          - id: x-parser-unique-object-id
            value: optionsPositionsDelta
    bindings: []
    extensions: *ref_0
sendOperations:
  - *ref_2
receiveOperations:
  - *ref_3
  - *ref_4
sendMessages:
  - *ref_5
receiveMessages:
  - *ref_6
  - *ref_7
extensions:
  - id: x-parser-unique-object-id
    value: positionsStream
securitySchemes:
  - id: wsAuth
    name: Sec-WebSocket-Protocol
    type: httpApiKey
    description: Supply as `authorization#<JWT>` during the WebSocket handshake.
    in: header
    extensions: []

````