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

# Get your portfolio

> The key owner's own paper portfolio in one call: the account, open positions (at most 500) and resting orders (at most 200), each naming the Arena instrument its market lists and the side held. Private picks included; the key's own main account only. No ticker, title or price while the venue-data switch is off. Not cached.



## OpenAPI

````yaml /openapi.json get /portfolio
openapi: 3.1.0
info:
  title: Arena API
  version: 1.7.0
  summary: >-
    Arena Predictions paper trading with an API key: read, and place paper
    orders with trade:write. Arena-owned data only.
  description: >-
    Arena Predictions (arena-predictions.com) is a sandbox for paper trading
    prediction markets at live prices. Every endpoint here serves Arena's
    sandbox, where every trade is a paper trade (mode "paper"); routing to live
    trading is coming. Keys are read-only and reach Arena-owned data only: the
    key's own identity and account, the leaderboards and published trader
    records with their resets and settled picks. Keys are managed with the
    signed-in browser session, never with a key. No exchange ticker, market
    title, entry price or venue price appears in any keyed response; the owner's
    own portfolio carries the owner's own paper numbers (a resting order's
    limitCents, a position's costDollars and contracts). Balances carry over:
    every account starts with 100,000 paper dollars, and a reset (at most one
    every 30 days, shown on a public profile) starts a new run. 1.2.0: seasons
    removed (no season field anywhere), leaderboard windows and kinds, trader
    resets, GET /account. 1.3.0: accounts are private by default. A private
    trader answers private: true with every P&L and rank null (resets and busts
    0) and an empty pick list; a public trader whose earlier trades are still
    hidden has numbersShown: false and no P&L or rank. The key owner reads their
    own picks (each with placedPrivate and shown) and their own eval rows (GET
    /me/eval) with portfolio:read. No key can make an account public. 1.4.0:
    keys are managed by a person's session, on the website or as a signed-in
    CLI's session token (arena keys), never by a key; keys rotate with a grace
    period; every keyed answer carries the plan and its counts (RateLimit-*,
    Arena-Quota-*, Arena-Plan) and GET /usage says where the account stands; a
    new scope, markets:read, reads instruments, games and quotes; GET /portfolio
    and /portfolio/trades read the owner's positions, orders and trades. Venue
    references and venue prices are served only while the venue-data switch is
    on (it ships off): until then the quotes routes answer 403 venue_data_off
    and nothing keyed names a ticker or a venue's price. 1.5.0: GET /eval, the
    public eval board (records:read), each row with 95% intervals clustered by
    game. 1.6.0: GET /traders/{traderId}/track-record, a trader's Ed25519-signed
    90-day record exactly as Arena signed it (records:read; it names Kalshi
    series inside its signed bytes, so it is served only while the venue-data
    switch is on), and tiedWithAbove on each eval row (null while this row's or
    the row above's interval is unknown). 1.7.0: a key created with trade:write
    (only when asked for by name: the Settings checkbox, arena keys create
    --trade, or scopes in the body) places paper orders with POST
    /portfolio/orders and cancels them with DELETE /portfolio/orders/{orderId},
    at Kalshi's paths. Market and limit orders, buys by instrument or ticker and
    sells of a whole position, each with an idempotencyKey: the same key again
    answers the stored order with replayed: true and places nothing. Hard trade
    limits are always enforced: per key 10 new orders a minute and 50 a day, and
    20 sells and cancels a minute; per account, across every key and connected
    app, 20 new orders a minute, 100 a day, and 40 sells and cancels a minute.
    The keyless website routes (/api/quotes/{instrumentId}, /api/quotes/batch,
    /api/gaps, /api/gaps/{instrumentId}) are described in their own document,
    /openapi-public.json.
  termsOfService: https://arena-predictions.com/terms
  contact:
    name: Arena
    email: support@zbgcllc.com
    url: https://arena-predictions.com/support
servers:
  - url: https://arena-predictions.com/api/v1
    description: >-
      The Arena API. Every account on it trades in the sandbox (paper trading);
      routing to live trading is coming.
security: []
tags:
  - name: Status
    description: Is the API up.
  - name: Identity
    description: Whose account a key acts for, and what it may do.
  - name: API keys
    description: >-
      Create, list, rotate and revoke keys, at the same path Kalshi uses. A
      person's session only (the website, or a signed-in CLI's session token): a
      key can never mint, rotate or revoke a key.
  - name: Records
    description: >-
      Arena's public records: the leaderboards, trader records with their
      resets, and settled picks. Scope records:read. Arena-owned data only: no
      exchange tickers, market titles, entry prices or live prices. Points equal
      paper dollars 1:1.
  - name: Portfolio
    description: >-
      The key owner's own paper account, positions, orders and trades. Scope
      portfolio:read. Arena-owned data only while the venue-data switch is off.
  - name: Markets
    description: >-
      Arena's instruments and games, and venue quotes. Scope markets:read. Venue
      references and prices only while the venue-data switch is on.
  - name: Trading
    description: >-
      Place and cancel paper orders for the key owner. Scope trade:write, which
      a key carries only when its creator asked for it. Paper only: nothing is
      sent to any venue.
  - name: Usage
    description: >-
      Where the key's account stands against its plan. Any valid key; never
      counted.
externalDocs:
  description: Arena API docs
  url: https://docs.arena-predictions.com
paths:
  /portfolio:
    get:
      tags:
        - Portfolio
      summary: Get your portfolio
      description: >-
        The key owner's own paper portfolio in one call: the account, open
        positions (at most 500) and resting orders (at most 200), each naming
        the Arena instrument its market lists and the side held. Private picks
        included; the key's own main account only. No ticker, title or price
        while the venue-data switch is off. Not cached.
      operationId: getPortfolio
      responses:
        '200':
          description: Your portfolio.
          headers:
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimit-Reset'
            Arena-Quota-Limit:
              $ref: '#/components/headers/Arena-Quota-Limit'
            Arena-Quota-Remaining:
              $ref: '#/components/headers/Arena-Quota-Remaining'
            Arena-Quota-Reset:
              $ref: '#/components/headers/Arena-Quota-Reset'
            Arena-Plan:
              $ref: '#/components/headers/Arena-Plan'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Portfolio'
        '400':
          description: 'invalid_request: GET /portfolio takes no parameters.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: >-
            Missing, malformed, unknown, revoked or expired key. Carries a
            WWW-Authenticate: Bearer challenge.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'insufficient_scope: the key does not carry portfolio:read.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            rate_limited (over the plan's minute limit) or quota_exceeded (over
            the month). Only while the limits are enforced; until then requests
            are counted and the headers set, and nothing is refused.
            error.retryAfterSeconds equals Retry-After.
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimit-Limit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimit-Remaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimit-Reset'
            Arena-Quota-Limit:
              $ref: '#/components/headers/Arena-Quota-Limit'
            Arena-Quota-Remaining:
              $ref: '#/components/headers/Arena-Quota-Remaining'
            Arena-Quota-Reset:
              $ref: '#/components/headers/Arena-Quota-Reset'
            Arena-Plan:
              $ref: '#/components/headers/Arena-Plan'
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: >-
            The key could not be verified, or the data could not be read, right
            now. Retry after the Retry-After seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - apiKey:
            - portfolio:read
components:
  headers:
    RateLimit-Limit:
      description: The plan's requests per minute (all keys of the account together).
      schema:
        type: integer
    RateLimit-Remaining:
      description: Requests left in this minute.
      schema:
        type: integer
    RateLimit-Reset:
      description: Seconds until the minute window resets.
      schema:
        type: integer
    Arena-Quota-Limit:
      description: The plan's requests per month (UTC).
      schema:
        type: integer
    Arena-Quota-Remaining:
      description: Requests left this month.
      schema:
        type: integer
    Arena-Quota-Reset:
      description: Seconds until 00:00 UTC on the 1st.
      schema:
        type: integer
    Arena-Plan:
      description: none (signed in, without a plan), basic, builder, desk or enterprise.
      schema:
        type: string
    X-Request-Id:
      description: Quote it when asking for help.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before trying again.
      schema:
        type: integer
  schemas:
    Portfolio:
      type: object
      required:
        - account
        - positions
        - positionsCount
        - positionsTruncated
        - orders
        - ordersCount
        - ordersTruncated
        - asOf
        - venueData
        - mode
      properties:
        account:
          oneOf:
            - $ref: '#/components/schemas/Account'
            - type: 'null'
          description: Null before the first trade.
        positions:
          type: array
          maxItems: 500
          items:
            $ref: '#/components/schemas/Position'
        positionsCount:
          type: integer
        positionsTruncated:
          type: boolean
        orders:
          type: array
          maxItems: 200
          items:
            $ref: '#/components/schemas/Order'
        ordersCount:
          type: integer
        ordersTruncated:
          type: boolean
        asOf:
          type: string
          format: date-time
        venueData:
          type: boolean
        mode:
          type: string
          const: paper
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Stable machine token. Branch on this, never on message.
              enum:
                - invalid_request
                - unauthorized
                - invalid_token
                - insufficient_scope
                - guest_account
                - scope_not_available
                - key_limit_reached
                - key_not_found
                - trader_not_found
                - account_not_found
                - route_not_found
                - method_not_allowed
                - internal_error
                - session_required
                - key_creation_limited
                - rate_limited
                - quota_exceeded
                - venue_data_off
                - instrument_not_found
                - game_not_found
                - membership_required
                - trading_off
                - idempotency_key_reused
                - insufficient_balance
                - market_not_found
                - no_tradable_listing
                - market_not_open
                - market_resolved
                - no_liquidity
                - price_moved
                - trade_not_found
                - already_closed
                - order_not_found
            message:
              type: string
              description: Human sentence. May change.
            retryAfterSeconds:
              type: integer
              minimum: 1
              description: 'On every 429: the same number as the Retry-After header.'
    Account:
      type: object
      required:
        - balanceDollars
        - netWorthDollars
        - openStakeDollars
        - heldDollars
        - openPositions
        - restingOrders
        - run
        - runStartedAt
        - startBalanceDollars
        - adjustmentsInRunDollars
        - pnlSinceResetDollars
        - selfResetEnabled
        - resetBlockedBy
        - nextResetAt
      properties:
        balanceDollars:
          type: number
          description: Spendable paper dollars.
        netWorthDollars:
          type: number
          description: Balance plus open positions at cost plus money held by resting buys.
        openStakeDollars:
          type: number
        heldDollars:
          type: number
          description: Held by resting buy orders.
        openPositions:
          type: integer
          minimum: 0
          description: How many. Positions themselves are not in this response.
        restingOrders:
          type: integer
          minimum: 0
        run:
          type: integer
          minimum: 0
          description: 0 until the first reset.
        runStartedAt:
          type:
            - string
            - 'null'
          format: date-time
        startBalanceDollars:
          type: number
          description: 'What the run started with: 100,000.'
        adjustmentsInRunDollars:
          type: number
          description: Operator corrections in this run. Not profit.
        pnlSinceResetDollars:
          type: number
          description: Net worth less the run's start and adjustments.
        selfResetEnabled:
          type: boolean
          description: Whether the owner turned resets on in Settings on the web.
        resetBlockedBy:
          type:
            - string
            - 'null'
          enum:
            - reset_not_enabled
            - cooldown
            - open_positions
            - nothing_to_reset
            - null
          description: What would refuse a reset right now, or null.
        nextResetAt:
          type:
            - string
            - 'null'
          format: date-time
          description: Set while the 30-day cooldown runs.
        lifetimePnlDollars:
          type: number
          description: Profit since 2026-09-01 across every run. Left out with run=current.
        resets:
          type: integer
          minimum: 0
          description: Left out with run=current.
        busts:
          type: integer
          minimum: 0
          description: Left out with run=current.
        lastResetAt:
          type:
            - string
            - 'null'
          format: date-time
          description: Left out with run=current.
    Position:
      type: object
      required:
        - tradeId
        - instrumentId
        - instrumentLabel
        - instrumentSide
        - boughtSide
        - contracts
        - costDollars
        - statedProbPct
        - placedVia
        - placedPrivate
        - parlayId
        - fillVenue
        - openedAt
      properties:
        tradeId:
          type: string
          format: uuid
        instrumentId:
          type:
            - string
            - 'null'
          description: The Arena instrument the market lists; null when not mapped.
        instrumentLabel:
          type:
            - string
            - 'null'
          description: The instrument's YES side in words.
        instrumentSide:
          type:
            - string
            - 'null'
          enum:
            - 'yes'
            - 'no'
            - null
          description: The side of the instrument held.
        boughtSide:
          type:
            - string
            - 'null'
          enum:
            - 'yes'
            - 'no'
            - null
          description: The side of the market bought.
        contracts:
          type: integer
        costDollars:
          type: number
          description: Paper dollars paid.
        statedProbPct:
          type:
            - integer
            - 'null'
          description: The probability you stated when placing, if any.
        placedVia:
          type:
            - string
            - 'null'
        placedPrivate:
          type: boolean
        parlayId:
          type:
            - string
            - 'null'
          format: uuid
        fillVenue:
          type: string
        openedAt:
          type:
            - string
            - 'null'
          format: date-time
        marketTicker:
          type:
            - string
            - 'null'
          description: Only while the venue-data switch is on.
        entryCents:
          type:
            - number
            - 'null'
          description: Only while the venue-data switch is on.
    Order:
      type: object
      required:
        - orderId
        - action
        - instrumentId
        - instrumentLabel
        - instrumentSide
        - orderSide
        - contracts
        - filledContracts
        - remainingContracts
        - limitCents
        - holdDollars
        - timeInForce
        - expiresAt
        - status
        - createdAt
      properties:
        orderId:
          type: string
          format: uuid
        action:
          type:
            - string
            - 'null'
          enum:
            - buy
            - sell
            - null
        instrumentId:
          type:
            - string
            - 'null'
        instrumentLabel:
          type:
            - string
            - 'null'
        instrumentSide:
          type:
            - string
            - 'null'
          enum:
            - 'yes'
            - 'no'
            - null
        orderSide:
          type:
            - string
            - 'null'
          enum:
            - 'yes'
            - 'no'
            - null
        contracts:
          type: integer
        filledContracts:
          type: integer
        remainingContracts:
          type: integer
        limitCents:
          type:
            - integer
            - 'null'
          description: Your own limit.
        holdDollars:
          type: number
        timeInForce:
          type:
            - string
            - 'null'
        expiresAt:
          type:
            - string
            - 'null'
          format: date-time
        status:
          type:
            - string
            - 'null'
        statedProbPct:
          type:
            - integer
            - 'null'
        placedVia:
          type:
            - string
            - 'null'
        placedPrivate:
          type: boolean
        createdAt:
          type:
            - string
            - 'null'
          format: date-time
        marketTicker:
          type:
            - string
            - 'null'
          description: Only while the venue-data switch is on.
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: arena_sk_ + 43 base64url characters
      description: >-
        Authorization: Bearer arena_sk_... (the x-arena-key header is accepted
        too). Keys are made in Settings
        (https://arena-predictions.com/settings#api-keys) or with `arena keys
        create`, shown once, stored hashed.

````