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

# List Positions

> Positions aggregated by predexon_id across routed venues

## Overview

Return the account's open positions grouped by outcome. The router fans out position reads to every routed venue in parallel, then groups per-venue holdings under a single `predexon_id`.

One position per outcome surfaces even when the partner holds it across multiple venues. Per-venue breakdowns are available on `positions[].venues[]`.

Top-level fields use the same names as their per-venue counterparts (`size`, `averagePrice`, `currentPrice`, `currentValue`, `pnl`, `status`, `result`) — the enclosing scope disambiguates. Each position carries:

* **Cost basis** (`averagePrice`) sourced directly from each venue's execution plane, which already tracks weighted-average cost across every source of fills — the router does not recompute attribution.
* **Live pricing** (`currentPrice`, `currentValue`, `pnl`) computed by the router from the streaming order-book feed using each venue's current top bid. Plane-reported values for these are intentionally not forwarded — they're periodic REST snapshots and would mislead partners on time-sensitive decisions.
* **Lifecycle state** (`status`, `result`) passed through from the plane.

See the [Order Router concept page](/concepts/order-router) for how `predexon_id` groups equivalent outcomes across venues.

## Path Parameters

| Param       | Type   | Description                                                                                                                                                                                |
| ----------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `accountId` | string | Trading account ID. Must belong to the calling API key. See the [Trading API accounts docs](https://docs.predexon.com/trading-api/accounts/create-account) for how to create and fund one. |

## Response Fields

### Top level

| Field            | Type  | Description                                                                                                                                                                                                                                         |
| ---------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `positions[]`    | array | Positions aggregated by `predexon_id`. One entry per outcome.                                                                                                                                                                                       |
| `unmapped[]`     | array | Positions the router doesn't carry on its live trading surface (resolved sports markets, non-sports markets). Surfaced as flat per-venue records — no cross-venue aggregation, no live pricing. See [Unmapped positions](#unmapped-position-entry). |
| `_meta.venues[]` | array | Per-venue read status.                                                                                                                                                                                                                              |

### Position entry

Fields are aggregated across every venue that holds the position. Per-venue values are preserved in `venues[]`.

| Field          | Type    | Description                                                                                                                                           |
| -------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `predexonId`   | string  | Canonical identifier of the outcome this position is in.                                                                                              |
| `title`        | string  | Human-readable outcome label.                                                                                                                         |
| `outcome`      | string  | Canonical outcome code.                                                                                                                               |
| `size`         | string  | Total shares held across every venue.                                                                                                                 |
| `averagePrice` | string? | Size-weighted mean of each venue's `averagePrice` (cost basis). Venues whose plane reports `null` are skipped from the weighting.                     |
| `currentPrice` | string? | Size-weighted mean of each venue's current top bid — equivalent to `currentValue / size`. `null` only when no venue has a live book for this outcome. |
| `currentValue` | string? | Aggregate market value of the position in stablecoin. Sum of per-venue `size × currentPrice` across venues with live books.                           |
| `pnl`          | string? | Unrealised profit and loss in stablecoin. `currentValue − sum(size × averagePrice)` across the contributing venues.                                   |
| `status`       | string? | `active`, `redeemable`, or `resolved`. `null` when no venue has reported a status yet. See [Lifecycle](#lifecycle).                                   |
| `result`       | string? | `won`, `lost`, or `null`.                                                                                                                             |
| `venues[]`     | array   | Per-venue breakdown.                                                                                                                                  |

### Per-venue entry

Every field on the position entry exists at the per-venue level with the per-venue value.

| Field          | Type    | Description                                                                                                                                                          |
| -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `venue`        | string  | `polymarket`, `predict`, `opinion`, or `limitless`.                                                                                                                  |
| `size`         | string  | Shares held on this venue.                                                                                                                                           |
| `averagePrice` | string? | Weighted-average cost basis on this venue, as reported by the venue's execution plane across every source of fills (router orders plus any direct per-venue orders). |
| `currentPrice` | string? | Top bid on this venue from the router's live order-book feed.                                                                                                        |
| `currentValue` | string? | `size × currentPrice`. `null` when no live book is available.                                                                                                        |
| `pnl`          | string? | `currentValue − (size × averagePrice)`.                                                                                                                              |
| `status`       | string? | `active`, `redeemable`, or `resolved`.                                                                                                                               |
| `result`       | string? | `won`, `lost`, or `null`.                                                                                                                                            |

### Unmapped position entry

`unmapped[]` carries positions the router cannot aggregate or live-price. Two cases produce these:

1. **Sports markets that have resolved.** Once the game finishes, the market drops off the router's live trading surface, but the partner still holds the redeemable token until claimed.
2. **Non-sports markets** (politics, news, crypto-binary, etc.). The router only routes sports markets, so positions on other markets always surface here — even while the market is fully active on its native venue.

Each entry is per-venue (no aggregation). `currentPrice`, `currentValue`, and `pnl` are omitted — they require a live order book that isn't available for these markets. Use the per-venue read at `GET /api/accounts/{accountId}/positions?venue={venue}` if you need live pricing on an unmapped position.

| Field          | Type    | Description                                                                                     |
| -------------- | ------- | ----------------------------------------------------------------------------------------------- |
| `venue`        | string  | `polymarket`, `predict`, `opinion`, or `limitless`.                                             |
| `tokenId`      | string  | The venue-native token identifier for this position.                                            |
| `predexonId`   | string? | Canonical identifier of the outcome this position is in.                                        |
| `size`         | string  | Shares held on this venue.                                                                      |
| `averagePrice` | string? | Cost basis.                                                                                     |
| `title`        | string? | Human-readable outcome label.                                                                   |
| `outcome`      | string? | Outcome code as reported by the venue (may differ from the canonical sports outcomes endpoint). |
| `status`       | string? | `active`, `redeemable`, or `resolved`.                                                          |
| `result`       | string? | `won`, `lost`, or `null`.                                                                       |

### `_meta.venues[]`

Per-venue read status. When a venue returned `error`, its positions are **not** reflected in the aggregated response — the other venues still return normally.

| Field    | Type   | Description      |
| -------- | ------ | ---------------- |
| `venue`  | string |                  |
| `status` | string | `ok` or `error`. |

## Lifecycle

### `status`

| Value        | Meaning                                                                                                          |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| `active`     | The market is still open and the position is tradeable.                                                          |
| `redeemable` | The market has resolved in the partner's favour and the position can be redeemed for stablecoin.                 |
| `resolved`   | The market has resolved and the position is fully settled — either redeemed already, or resolved with no payout. |
| `null`       | No venue has reported a lifecycle status for this position yet.                                                  |

### `result`

| Value  | Meaning                                                                                       |
| ------ | --------------------------------------------------------------------------------------------- |
| `null` | Market is still active, or not every venue has finalised.                                     |
| `won`  | Outcome resolved in the partner's favour on at least one venue — there is something to claim. |
| `lost` | Every venue reported `lost`.                                                                  |

### Aggregation across venues

When a position exists on multiple venues, the top-level fields are derived from each venue as follows:

| Top-level field | Rule                                                                                                                  |
| --------------- | --------------------------------------------------------------------------------------------------------------------- |
| `size`          | Sum of per-venue `size`.                                                                                              |
| `averagePrice`  | Size-weighted mean of per-venue `averagePrice`, skipping venues whose plane reported `null`.                          |
| `currentPrice`  | Size-weighted mean of per-venue top bid (equivalent to `currentValue / size`).                                        |
| `currentValue`  | Sum of per-venue `size × currentPrice`. Venues without a live book contribute nothing.                                |
| `pnl`           | `currentValue − sum(size × averagePrice)` across contributing venues.                                                 |
| `status`        | Any `active` → `active`. Else any `redeemable` → `redeemable`. Else `resolved`. `null` if no venue reported a status. |
| `result`        | Any `won` → `won`. All `lost` → `lost`. Else `null`.                                                                  |

## Example

`GET /api/accounts/acc_8f2e/router/positions`

```json theme={null}
{
  "positions": [
    {
      "predexonId": "px-uvtpjis2k7bj",
      "title": "Atlanta Hawks",
      "outcome": "atl",
      "size": "29.935000",
      "averagePrice": "0.335488",
      "currentPrice": "0.352000",
      "currentValue": "10.537120",
      "pnl": "0.495042",
      "status": "active",
      "result": null,
      "venues": [
        {
          "venue": "polymarket",
          "size": "18.115000",
          "averagePrice": "0.331200",
          "currentPrice": "0.352000",
          "currentValue": "6.376480",
          "pnl": "0.376842",
          "status": "active",
          "result": null
        },
        {
          "venue": "predict",
          "size": "11.820000",
          "averagePrice": "0.342000",
          "currentPrice": "0.352000",
          "currentValue": "4.160640",
          "pnl": "0.118200",
          "status": "active",
          "result": null
        }
      ]
    }
  ],
  "unmapped": [
    {
      "venue": "polymarket",
      "tokenId": "59005039819817191572790632185216584675790282938177567233176230080432531995226",
      "predexonId": "px-fegdlyupysfg",
      "size": "1.49",
      "averagePrice": "0.666798",
      "title": "Spurs vs. Trail Blazers",
      "outcome": "Spurs",
      "status": "redeemable",
      "result": "won"
    },
    {
      "venue": "polymarket",
      "tokenId": "8501497159083948713316135768103773293754490207922884688769443031624417212426",
      "predexonId": "px-ytpcgddmjldm",
      "size": "5.45",
      "averagePrice": "0.549999",
      "title": "Russia-Ukraine Ceasefire before GTA VI?",
      "outcome": "Yes",
      "status": "active",
      "result": null
    }
  ],
  "_meta": {
    "venues": [
      { "venue": "polymarket", "status": "ok" },
      { "venue": "predict", "status": "ok" },
      { "venue": "opinion", "status": "ok" },
      { "venue": "limitless", "status": "ok" }
    ]
  }
}
```

<Info>
  `currentPrice`, `currentValue`, and `pnl` are computed by the router using the live top-of-book bid for each venue — they are not passed through from plane-reported values, which can be stale. `averagePrice` is always plane-sourced and reflects every fill that contributed to the position, including fills from sources outside the router.
</Info>

<Info>
  When `_meta.venues[].status` is `error` for any venue, the aggregated `positions[]` reflects only the healthy venues. Re-call the endpoint after a short delay to pick up the missing venue once reads recover — a brief transient on one venue does not roll back the response.
</Info>

<Info>
  `unmapped[]` is **not** a degraded mode — it's the design for any position outside the router's live trading surface. Resolved sports positions (waiting to be redeemed) and non-sports positions (politics, news, etc.) belong here permanently. Reconcile against `predexonId` like you would for `positions[]`. The shape is intentionally flatter (no `venues[]` aggregation, no live pricing) — partners that need a live price for these positions should call `GET /api/accounts/{accountId}/positions?venue={venue}`.
</Info>


## OpenAPI

````yaml GET /api/accounts/{accountId}/router/positions
openapi: 3.1.0
info:
  title: Predexon Order Router API
  description: >-
    Unified cross-venue smart order routing across Polymarket, Predict.fun,
    Opinion, and Limitless
  version: 1.0.0
servers:
  - url: https://trade.predexon.com
security:
  - apiKeyAuth: []
paths:
  /api/accounts/{accountId}/router/positions:
    get:
      tags:
        - router
      summary: List Positions
      description: >-
        Return the account's open positions grouped by outcome. Per-venue
        holdings are aggregated under a single `predexonId`. Positions outside
        the router's live trading surface (resolved sports markets, non-sports
        markets) surface in `unmapped[]` instead — same `predexonId`
        reconciliation, no aggregation. Partial venue failures are surfaced via
        `_meta.venues[]` — the aggregated list still returns whatever the
        healthy venues reported.
      operationId: getRouterPositions
      parameters:
        - name: accountId
          in: path
          required: true
          schema:
            type: string
          description: Account ID. Must belong to the calling API key.
      responses:
        '200':
          description: Positions aggregated across routed venues.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PositionsResponse'
              example:
                positions:
                  - predexonId: px-uvtpjis2k7bj
                    title: Atlanta Hawks
                    outcome: atl
                    size: '29.935000'
                    averagePrice: '0.335488'
                    currentPrice: '0.352000'
                    currentValue: '10.537120'
                    pnl: '0.495042'
                    status: active
                    result: null
                    venues:
                      - venue: polymarket
                        size: '18.115000'
                        averagePrice: '0.331200'
                        currentPrice: '0.352000'
                        currentValue: '6.376480'
                        pnl: '0.376842'
                        status: active
                        result: null
                      - venue: predict
                        size: '11.820000'
                        averagePrice: '0.342000'
                        currentPrice: '0.352000'
                        currentValue: '4.160640'
                        pnl: '0.118200'
                        status: active
                        result: null
                unmapped:
                  - venue: polymarket
                    tokenId: >-
                      59005039819817191572790632185216584675790282938177567233176230080432531995226
                    predexonId: px-fegdlyupysfg
                    size: '1.49'
                    averagePrice: '0.666798'
                    title: Spurs vs. Trail Blazers
                    outcome: Spurs
                    status: redeemable
                    result: won
                  - venue: polymarket
                    tokenId: >-
                      8501497159083948713316135768103773293754490207922884688769443031624417212426
                    predexonId: px-ytpcgddmjldm
                    size: '5.45'
                    averagePrice: '0.549999'
                    title: Russia-Ukraine Ceasefire before GTA VI?
                    outcome: 'Yes'
                    status: active
                    result: null
                _meta:
                  venues:
                    - venue: polymarket
                      status: ok
                    - venue: predict
                      status: ok
                    - venue: opinion
                      status: ok
                    - venue: limitless
                      status: ok
components:
  schemas:
    PositionsResponse:
      type: object
      required:
        - positions
        - unmapped
        - _meta
      properties:
        positions:
          type: array
          description: >-
            Positions aggregated by `predexonId`. One entry per outcome,
            regardless of how many venues the partner holds it on.
          items:
            $ref: '#/components/schemas/AggregatedPosition'
        unmapped:
          type: array
          description: >-
            Positions the router doesn't carry on its live trading surface. Two
            cases: (1) sports markets that have resolved (`status: resolved` or
            `redeemable`); (2) non-sports markets (politics, news,
            crypto-binary), which always surface here. No aggregation, no live
            pricing.
          items:
            $ref: '#/components/schemas/UnmappedPosition'
        _meta:
          type: object
          required:
            - venues
          properties:
            venues:
              type: array
              description: >-
                Per-venue read status. When a venue returned `error`, its
                positions are not reflected in the aggregated response — the
                other venues still return normally.
              items:
                type: object
                required:
                  - venue
                  - status
                properties:
                  venue:
                    $ref: '#/components/schemas/Venue'
                  status:
                    type: string
                    enum:
                      - ok
                      - error
    AggregatedPosition:
      type: object
      description: >-
        Top-level fields use the same names as their per-venue counterparts in
        `venues[]`; the enclosing scope disambiguates.
      required:
        - predexonId
        - title
        - outcome
        - size
        - averagePrice
        - currentPrice
        - currentValue
        - pnl
        - status
        - result
        - venues
      properties:
        predexonId:
          type: string
          description: Canonical identifier of the outcome this position is in.
        title:
          type: string
          description: Human-readable outcome label.
        outcome:
          type: string
          description: Canonical outcome code.
        size:
          type: string
          description: Total shares held across every routed venue.
        averagePrice:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Size-weighted mean of each venue's `averagePrice` (cost basis),
            across the venues that hold this position. Venues whose plane
            reports `null` are skipped from the weighting.
        currentPrice:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Size-weighted mean of each venue's current top bid, equivalent to
            `currentValue / size`. `null` only when no venue has a live book for
            this outcome.
        currentValue:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Aggregate market value of the position, expressed in stablecoin. Sum
            of per-venue `size × currentPrice` across venues with live books.
        pnl:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Unrealised profit and loss, in stablecoin. `currentValue − sum(size
            × averagePrice)` across the contributing venues.
        status:
          $ref: '#/components/schemas/PositionStatus'
        result:
          $ref: '#/components/schemas/PositionResult'
        venues:
          type: array
          description: >-
            Per-venue breakdown of the position. Every field that exists at the
            top level also exists at the per-venue level with the per-venue
            value.
          items:
            type: object
            required:
              - venue
              - size
              - averagePrice
              - currentPrice
              - currentValue
              - pnl
              - status
              - result
            properties:
              venue:
                $ref: '#/components/schemas/Venue'
              size:
                type: string
                description: Shares held on this venue.
              averagePrice:
                oneOf:
                  - type: string
                  - type: 'null'
                description: >-
                  Weighted-average cost basis on this venue, as reported by the
                  venue's execution plane across every source of fills (router
                  orders plus any direct per-venue orders).
              currentPrice:
                oneOf:
                  - type: string
                  - type: 'null'
                description: >-
                  Top bid on this venue from the router's live order-book feed.
                  `null` when the book is unavailable.
              currentValue:
                oneOf:
                  - type: string
                  - type: 'null'
                description: >-
                  Market value of the per-venue holding, `size × currentPrice`.
                  `null` when no live book is available.
              pnl:
                oneOf:
                  - type: string
                  - type: 'null'
                description: >-
                  Unrealised P&L on this venue, `currentValue − (size ×
                  averagePrice)`.
              status:
                $ref: '#/components/schemas/PositionStatus'
              result:
                $ref: '#/components/schemas/PositionResult'
    UnmappedPosition:
      type: object
      description: >-
        A position the router can identify but doesn't carry on its live trading
        surface. Surfaces for resolved sports markets and for non-sports markets
        (politics, news, crypto-binary).
      required:
        - venue
        - tokenId
        - predexonId
        - size
        - averagePrice
        - title
        - outcome
        - status
        - result
      properties:
        venue:
          $ref: '#/components/schemas/Venue'
        tokenId:
          type: string
          description: Venue-native token identifier for this position.
        predexonId:
          oneOf:
            - type: string
            - type: 'null'
          description: Canonical identifier of the outcome this position is in.
        size:
          type: string
          description: Shares held on this venue.
        averagePrice:
          oneOf:
            - type: string
            - type: 'null'
          description: Cost basis.
        title:
          oneOf:
            - type: string
            - type: 'null'
          description: Human-readable label.
        outcome:
          oneOf:
            - type: string
            - type: 'null'
          description: >-
            Outcome code as reported by the venue (may differ from the canonical
            sports outcomes endpoint).
        status:
          $ref: '#/components/schemas/PositionStatus'
        result:
          $ref: '#/components/schemas/PositionResult'
    Venue:
      type: string
      enum:
        - polymarket
        - predict
        - opinion
        - limitless
      description: A routed venue.
    PositionStatus:
      oneOf:
        - type: string
          enum:
            - active
            - redeemable
            - resolved
        - type: 'null'
      description: >-
        Lifecycle status of the position. `active` — the market is still open
        and the position is tradeable. `redeemable` — the market has resolved in
        the partner's favour and the position can be redeemed for stablecoin.
        `resolved` — the market has resolved and the position is fully settled
        (either redeemed, or resolved with no payout). `null` when no venue has
        reported a status for this position yet.
    PositionResult:
      oneOf:
        - type: string
          enum:
            - won
            - lost
        - type: 'null'
      description: >-
        Resolution outcome. `null` while the market is still active or has not
        finalised on every venue; `won` if the outcome resolved in the partner's
        favour on any venue; `lost` when every venue reported `lost`.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Trading key provided by Predexon. The data key used by the Sports
        Discovery API on api.predexon.com is a separate credential.

````