Arena Identity API

Whose account a key acts for, which organizations it belongs to, and what it may do.

Operations 2

GET /me Get me #
GET /organizations List your organizations #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/arena-predictions-com:arena-predictions-com-identity-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

arena-predictions-com-identity-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Arena Identity API
  version: 1.15.0
  summary: 'Arena with an API key: read Arena-owned data, place paper orders with trade:write, and send live orders to your own venue account with a venue''s live-order scope.'
  description: 'Arena Predictions (arena-predictions.com) is paper trading for prediction markets at live prices, in a sandbox, and live orders through the key owner''s own venue credentials. Paper is the default on every endpoint here (mode "paper"): a paper trade fills in Arena''s sandbox and is not sent to a venue. A live order is sent only when a request says execution kalshi or poly-intl with a key made with trade:write:kalshi or trade:write:poly-intl. It goes to the key owner''s own Kalshi or Polymarket International account with the venue credentials saved in Settings: real money at the venue, under the venue''s rules and terms. Arena is not a broker and never holds your funds. Polymarket International is not for US persons, and ProphetX orders are switched off (trade:write:prophetx is not issued, so execution prophetx is refused with 403 insufficient_scope; a key that carries the scope gets 503 trading_off). Keys read by default 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 a paper answer or a read while the venue-data switch is off; the owner''s own portfolio carries the owner''s own paper numbers (a resting order''s limitCents, a position''s costDollars and contracts). A live order''s answer names the venue''s own market and price (ticker, priceCents). 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.'
  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. Paper trading, Arena's sandbox, is the default on every account. An order is sent to a venue only when the request says execution and the key carries that venue's scope.
tags:
- name: Identity
  description: Whose account a key acts for, which organizations it belongs to, and what it may do.
paths:
  /me:
    get:
      tags:
      - Identity
      operationId: getMe
      summary: Get me
      description: Whose account the presented key acts for, which scopes it carries, and whether it is paper only. limits is the plan's minute and month, the same numbers as the RateLimit and Arena-Quota headers. Needs a valid key and no particular scope, so an agent can discover its own permissions before trying anything that could fail.
      security:
      - apiKey: []
      responses:
        '200':
          description: The key's identity and scopes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Me'
        '401':
          description: 'Missing, malformed, unknown, revoked or expired key. Carries a WWW-Authenticate: Bearer challenge.'
          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 right now. Retry after the Retry-After seconds; the key may be perfectly good.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /organizations:
    get:
      tags:
      - Identity
      operationId: listOrganizations
      summary: List your organizations
      description: 'The organizations this personal API key belongs to. Any valid key, no particular scope. Forwarded to the organizations edge function: the anon key is only the gateway bearer, and the caller''s key goes in X-Arena-Key. The function''s JSON is returned. A 2xx object has mode paper (set here when the function left it out). Each organization''s id is what X-Arena-Org takes on GET /portfolio, GET /portfolio/trades, POST /portfolio/orders and DELETE /portfolio/orders/{orderId}. This route ignores X-Arena-Org and does not select a sandbox or a Combine evaluation account. GET takes no query parameters. POST and every other method answer 405 method_not_allowed and are not forwarded. Paper only. Not cached.'
      security:
      - apiKey: []
      responses:
        '200':
          description: The organizations this key belongs to. mode is paper.
          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/OrganizationList'
              example:
                organizations:
                - id: aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee
                  slug: acme
                  name: Acme
                  role: member
                mode: paper
        '400':
          description: 'invalid_request: GET /organizations takes no query 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'
        '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 organizations could not be listed, right now. Retry after the Retry-After seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    OrganizationList:
      type: object
      required:
      - organizations
      - mode
      properties:
        organizations:
          type: array
          description: The organizations this personal key belongs to. Empty when it belongs to none.
          items:
            $ref: '#/components/schemas/Organization'
        mode:
          type: string
          const: paper
      additionalProperties: true
    Me:
      type: object
      required:
      - user
      - key
      - mode
      - paperOnly
      - limits
      properties:
        user:
          type: object
          required:
          - id
          - displayName
          - private
          properties:
            id:
              type: string
              format: uuid
            displayName:
              type:
              - string
              - 'null'
            private:
              type:
              - boolean
              - 'null'
              description: 'Accounts are private by default: others see none of this account''s trades or numbers until its owner makes the profile public in Settings on the website. Null when it could not be read.'
        key:
          type: object
          required:
          - prefix
          - scopes
          properties:
            prefix:
              type: string
            scopes:
              type: array
              items:
                type: string
        mode:
          type: string
          const: paper
        paperOnly:
          type: boolean
          description: True unless this key carries a live-order scope (trade:write:kalshi, trade:write:poly-intl or trade:write:prophetx). A paper-only key's trades fill in Arena's sandbox and are not sent to a venue.
        limits:
          type:
          - object
          - 'null'
          description: The plan's minute and month. The same numbers as the RateLimit and Arena-Quota headers. Null when the server could not read them.
          required:
          - minute
          - month
          - enforced
          properties:
            minute:
              type: object
              required:
              - limit
              - remaining
              properties:
                limit:
                  type: integer
                  minimum: 0
                remaining:
                  type: integer
                  minimum: 0
            month:
              type: object
              required:
              - limit
              - used
              properties:
                limit:
                  type: integer
                  minimum: 0
                used:
                  type: integer
                  minimum: 0
            enforced:
              type: boolean
              description: When false, a request over the limit is still answered and only the count is kept.
    Organization:
      type: object
      required:
      - id
      description: One organization this key's account belongs to. id is the UUID to send as X-Arena-Org. The organizations edge function may add fields; they are passed through. Paper only.
      properties:
        id:
          type: string
          format: uuid
        slug:
          type:
          - string
          - 'null'
        name:
          type:
          - string
          - 'null'
        role:
          type:
          - string
          - 'null'
          description: The key owner's membership, such as member.
      additionalProperties: true
    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
              - consolidated_book_off
              - instrument_not_found
              - game_not_found
              - membership_required
              - trading_off
              - kalshi_key_missing
              - kalshi_rejected
              - poly_intl_key_missing
              - poly_intl_rejected
              - us_not_eligible
              - prophetx_key_missing
              - prophetx_rejected
              - not_configured
              - live_trading_unavailable
              - 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
              - organization_not_found
              - organization_forbidden
            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.'
  headers:
    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
    Arena-Plan:
      description: none (signed in, without a plan), basic, builder, desk or enterprise.
      schema:
        type: string
    RateLimit-Reset:
      description: Seconds until the minute window resets.
      schema:
        type: integer
    RateLimit-Remaining:
      description: Requests left in this minute.
      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
    RateLimit-Limit:
      description: The plan's requests per minute (all keys of the account together).
      schema:
        type: integer
    Arena-Quota-Reset:
      description: Seconds until 00:00 UTC on the 1st.
      schema:
        type: integer
  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.'
    session:
      type: apiKey
      in: cookie
      name: sb-access-token
      description: The signed-in browser session (Google or Apple). Used only for key management, same-origin JSON requests only. An API key presented here is refused (401 session_required).
    sessionBearer:
      type: http
      scheme: bearer
      bearerFormat: Supabase access token (JWT) of a signed-in person
      description: 'A signed-in person''s session token, as the CLI sends it after arena login. Key management checks it with the auth server (JSON bodies required; an arena_sk_ key there is 401 session_required). POST /backtest, POST /evals, GET /runs and GET /runs/{run_id} take it in place of a key and forward it to the backtest function, which checks it with the auth server. A bearer that starts with arena_sk_ is always read as a key. Never a guest session (403 guest_account) or a connected app''s OAuth token (401 session_required). Every other keyed route answers it 401 unauthorized: that route takes an API key.'
externalDocs:
  description: Arena API docs
  url: https://docs.arena-predictions.com