{"openapi":"3.1.0","info":{"title":"BettorEdge API","version":"1.0.0","description":"Read live markets and place trades on a peer-to-peer sports exchange. Prices are probabilities, and any position can be sold before the event ends.\n\n`{brand}` in every path is your partner slug, or `bettoredge` (your personal API path) with a personal token.\n\n## Two ways in\n\n**Trade your own account** (a script or bot for yourself):\n\n1. In the BettorEdge app open Account → Connected Apps and create a personal access token. Choose scopes (`portfolio:read`, `orders:write`), the IP addresses it may be used from (required), and an expiry of 1–365 days.\n2. Send it as `Authorization: Bearer <token>` with no `x-api-key`, under your personal API path `/v1/bettoredge/`.\n3. No portal sign-up. Reads work straight away; order access is enabled on request — email api@bettoredge.com.\n\n**Build for other players** (an app other people connect to):\n\n1. Sign up in the developer portal for a partner API key (sandbox first) and your path `/v1/{brand}/`.\n2. Send the key as `x-api-key` on every request. Market data needs nothing else.\n3. For a player's portfolio or orders, also send that player's OAuth access token (below) as `Authorization: Bearer`. Never ask a player for their password.\n\nEvery portfolio and order endpoint acts on the account the token belongs to.\n\n## Prices\n\nEvery price is a probability between 0 and 1, never American or decimal odds.\n\n## Trading a line\n\nRead `markets/available`, take the `order_context_hash` from the line you want, and pass it to `orders/place`. The hash is opaque — do not parse or construct it.\n\n## Order types and slippage\n\n`orders/place` takes `order_type`: `'limit'` (default) fills at `price` or better, never worse; `'market'` may fill up to `price + max_slippage`. `max_slippage` is in probability points on the 0-1 price (0.02 = 2 cents), greater than 0 and at most 0.03, and only on a market order: a buy at 0.53 with 0.02 fills at up to 0.55. Sales are limit-only — `price` is the lowest a sale accepts (selling at 0.53 never fills below 0.53), and `order_type: 'market'` on a sale is a 422 `VALIDATION_ERROR`. Whatever does not fill at once keeps working, with its tolerance, until `expire_time` — there is no immediate-or-cancel, so send a short `expire_time` to stop an unfilled order quickly. Every order in a response or event reports its real `order_type`.\n\n## Money\n\nEvery money amount in a response or event is rounded to the cent. Contracts keep six decimal places; prices are never rounded. On a cancelled or expired order, `open_amount` is what was still open when it stopped — check `status`, not `open_amount`, to know whether an order is working.\n\n## Refused orders\n\nA 200 from orders/place or orders/sell means the order was accepted. A refused order is a 4xx/5xx with an error `code` — `INSUFFICIENT_FUNDS` (422), `MARKET_CLOSED` (409), `INVALID_SELECTION` / `INVALID_PRICE` / `INVALID_AMOUNT` / `INVALID_EXPIRY` / `NO_POSITION` / `VALIDATION_ERROR` (422), `KYC_REQUIRED` / `API_TERMS_REQUIRED` / `LOCATION_REQUIRED` / `LOCATION_NOT_ALLOWED` / `OUTSIDE_US` / `IP_PROXY_DETECTED` / `SANDBOX_FREE_ONLY` (403), `ORDER_NOT_FOUND` (404), `ORDER_REJECTED` (422), `BALANCE_UNAVAILABLE` / `LOCATION_CHECK_UNAVAILABLE` (503, with `Retry-After`) and `UPSTREAM_ERROR` (502). Nothing is created or spent on a refusal.\n\n## Location (real money)\n\nReal-money orders made for another player (OAuth) need that player's location confirmed in the BettorEdge app within the last 7 days, else `LOCATION_REQUIRED`. Real-money orders on a personal token are checked against the calling IP on every order (no VPN, proxy or hosting-provider addresses). Edge Coin (`FREE`) orders have no location check.\n\n## Sandbox (partner keys)\n\nA sandbox key trades the real board at real prices with Edge Coins (play money) only. Orders must send `market_type: 'FREE'`; sells are not available; cancels are limited to the account's own Edge Coin orders. Anything else is refused with `SANDBOX_FREE_ONLY`. Every response carries `X-Pulse-Environment: sandbox|production`.\n\n## Streaming\n\nLive market data and order events over one WebSocket: `wss://<host>/v1/{brand}/stream`. Partners send `x-api-key` on the upgrade (or `{\"op\":\"auth\",\"api_key\":\"…\"}` as the first frame within 5s); a personal token connects to `/v1/bettoredge/stream` with `Authorization: Bearer`. Subscribe with `{\"op\":\"subscribe\",\"channel\":\"contest\",\"contest_id\":\"…\"}`, `\"league\"` (`league_id`), `\"depth\"` (`order_context_hash`) or `\"orders\"`; every subscribe is acked with a snapshot shaped exactly like the REST response, then `contest`, `contest_state`, `depth` and `order` frames follow. Order events (`order.placed`, `order.filled`, `order.cancelled`, `order.expired`, `position.settled`) name the player and arrive only for players who granted `portfolio:read`. `order.placed` (event key `order.placed:<order_id>`) is sent for buys placed through `orders/place` only — an order placed in the BettorEdge app, or a sale, first appears as its fill, cancel or expiry. A revoke stops them at once. Delivery is at most once: on reconnect, reconcile with `portfolio/orders` and order activity, deduping on `event_id`. Caps: 3 connections per credential, 10 per partner; per connection 100 contests, 200 depth lines, 10 leagues, 20 ops/s. Close codes: 4001 unauthenticated / revoked, 4003 forbidden, 4008 slow consumer, 4029 too many connections.\n\n## Rate limits\n\nPer key, per second and per minute, with separate budgets for reads and orders. Order endpoints are also capped per account, so one account cannot absorb your whole budget. A 429 says which limit was hit in `limit_scope` (`key` or `player`).\n\n\n\n## Player tokens for partners (OAuth 2.0)\n\nUse the authorization code flow with PKCE:\n\n1. Register an OAuth client (exact redirect URIs). Confidential clients get a `client_secret`, shown once.\n2. Send the player's browser to `https://pulse.bettoredge.com/oauth/authorize` with `response_type=code`, `client_id`, `redirect_uri`, `scope` (space-separated: `portfolio:read`, `orders:write`), `state`, `code_challenge` and `code_challenge_method=S256`. PKCE is required for every client; `plain` is refused.\n3. The player signs in to BettorEdge, sees your app name and the exact scopes, and approves or declines. You get `code` + `state` (or `error=access_denied`) at your redirect URI. Check `state`.\n4. Within 60 seconds, POST `grant_type=authorization_code`, `code`, `redirect_uri`, `code_verifier` to `https://pulse.bettoredge.com/oauth/token`, authenticating with HTTP Basic (`client_id:client_secret`) or `client_id` alone for a public client.\n5. You receive a 15-minute `access_token` (send it as `Authorization: Bearer` alongside your `x-api-key`) and a `refresh_token`. Refresh with `grant_type=refresh_token`; every refresh returns a NEW refresh token and retires the old one. Presenting a retired refresh token revokes the whole authorization — store the newest one atomically.\n\nA player token only works with YOUR partner's API key, and stops working the moment the player disconnects your app. POST the token to `https://pulse.bettoredge.com/oauth/revoke` to disconnect from your side. A personal access token sent with a partner key is refused: partners use OAuth."},"servers":[{"url":"https://pulse.bettoredge.com"}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Build for other players: your partner API key from the developer portal."},"playerOAuth":{"type":"oauth2","description":"Build for other players: a player's authorization for your app, sent as `Authorization: Bearer` alongside your `x-api-key`.","flows":{"authorizationCode":{"authorizationUrl":"https://pulse.bettoredge.com/oauth/authorize","tokenUrl":"https://pulse.bettoredge.com/oauth/token","refreshUrl":"https://pulse.bettoredge.com/oauth/token","scopes":{"portfolio:read":"See the player's positions, orders and what happened to them","orders:write":"Place, sell and cancel orders using the player's balance"}}}},"personalToken":{"type":"http","scheme":"bearer","description":"Trade your own account: a personal access token from the BettorEdge app (Account → Connected Apps), sent WITHOUT an x-api-key, under your personal API path /v1/bettoredge/."}},"schemas":{"Contest":{"type":"object","properties":{"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"league_id":{"type":"string"},"title":{"type":"string"},"scheduled_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"liquidity":{"type":"number","description":"Sum of available across every market, in dollars. Rounded to the cent."},"volume":{"type":"number","description":"Sum of traded volume across every market, in dollars. Rounded to the cent."},"participants":{"type":"array","items":{"type":"object","properties":{"participant_id":{"type":"string"},"name":{"type":"string"},"alignment":{"type":"string","description":"'home' or 'away' on team contests; absent otherwise."}},"required":["participant_id","name"],"additionalProperties":false,"description":"A team or athlete taking part."}},"markets":{"type":"array","items":{"type":"object","properties":{"market_id":{"type":"string"},"description":{"type":"string","description":"What the market is, e.g. \"Moneyline\" or \"Total Points\"."},"level":{"type":"string","enum":["contest","team","athlete"]},"is_spread_market":{"type":"boolean"},"liquidity":{"type":"number","description":"Sum of available across every side, in dollars. Rounded to the cent."},"volume":{"type":"number","description":"Cumulative traded volume, in dollars. Rounded to the cent."},"sides":{"type":"array","items":{"type":"object","properties":{"side":{"type":"string","description":"Display name of the side."},"side_id":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"best_price":{"type":"number","description":"Best (cheapest) taker price. Absent when nothing is offered on this side."},"liquidity":{"type":"number","description":"Sum of `available` across every line below, in dollars. Rounded to the cent."},"last_trade":{"type":"object","properties":{"price":{"type":"number"},"amount":{"type":"number","description":"Stake matched, in dollars. Rounded to the cent."},"traded_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."}},"required":["price","amount","traded_at"],"additionalProperties":false,"description":"The most recent fill on this side."},"lines":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"Identifier for one tradeable line — pass to orders/place and orders/sell. Opaque: its internal composition is not part of this contract and may change. Read it, never build it."},"variable":{"type":"number","description":"The line — a spread, a total, or 0 for a moneyline."},"price":{"type":"number","description":"Taker price as a probability, 0-1. Never American or decimal odds."},"available":{"type":"number","description":"Total amount available on this line across EVERY price, in dollars. Rounded to the cent. Only `top_available` fills at `price`; the rest fills at worse prices (see /markets/depth)."},"top_available":{"type":"number","description":"Amount available at exactly `price` (the top of the book), in dollars. Rounded to the cent. This is what a taker can get at the price shown."}},"required":["order_context_hash","variable","price","available","top_available"],"additionalProperties":false,"description":"One tradeable line, and the hash needed to trade it."},"description":"Every tradeable line. Empty means nobody is offering — you can still post a price."}},"required":["side","side_id","side_type","liquidity","lines"],"additionalProperties":false,"description":"One side of a market, with its depth."}}},"required":["market_id","description","level","is_spread_market","liquidity","volume","sides"],"additionalProperties":false,"description":"One market on a contest."}}},"required":["contest_id","contest_type","league_id","title","scheduled_at","liquidity","volume","participants","markets"],"additionalProperties":false,"description":"A game, tournament or match, with every market on it."},"Market":{"type":"object","properties":{"market_id":{"type":"string"},"description":{"type":"string","description":"What the market is, e.g. \"Moneyline\" or \"Total Points\"."},"level":{"type":"string","enum":["contest","team","athlete"]},"is_spread_market":{"type":"boolean"},"liquidity":{"type":"number","description":"Sum of available across every side, in dollars. Rounded to the cent."},"volume":{"type":"number","description":"Cumulative traded volume, in dollars. Rounded to the cent."},"sides":{"type":"array","items":{"type":"object","properties":{"side":{"type":"string","description":"Display name of the side."},"side_id":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"best_price":{"type":"number","description":"Best (cheapest) taker price. Absent when nothing is offered on this side."},"liquidity":{"type":"number","description":"Sum of `available` across every line below, in dollars. Rounded to the cent."},"last_trade":{"type":"object","properties":{"price":{"type":"number"},"amount":{"type":"number","description":"Stake matched, in dollars. Rounded to the cent."},"traded_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."}},"required":["price","amount","traded_at"],"additionalProperties":false,"description":"The most recent fill on this side."},"lines":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"Identifier for one tradeable line — pass to orders/place and orders/sell. Opaque: its internal composition is not part of this contract and may change. Read it, never build it."},"variable":{"type":"number","description":"The line — a spread, a total, or 0 for a moneyline."},"price":{"type":"number","description":"Taker price as a probability, 0-1. Never American or decimal odds."},"available":{"type":"number","description":"Total amount available on this line across EVERY price, in dollars. Rounded to the cent. Only `top_available` fills at `price`; the rest fills at worse prices (see /markets/depth)."},"top_available":{"type":"number","description":"Amount available at exactly `price` (the top of the book), in dollars. Rounded to the cent. This is what a taker can get at the price shown."}},"required":["order_context_hash","variable","price","available","top_available"],"additionalProperties":false,"description":"One tradeable line, and the hash needed to trade it."},"description":"Every tradeable line. Empty means nobody is offering — you can still post a price."}},"required":["side","side_id","side_type","liquidity","lines"],"additionalProperties":false,"description":"One side of a market, with its depth."}}},"required":["market_id","description","level","is_spread_market","liquidity","volume","sides"],"additionalProperties":false,"description":"One market on a contest."},"Side":{"type":"object","properties":{"side":{"type":"string","description":"Display name of the side."},"side_id":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"best_price":{"type":"number","description":"Best (cheapest) taker price. Absent when nothing is offered on this side."},"liquidity":{"type":"number","description":"Sum of `available` across every line below, in dollars. Rounded to the cent."},"last_trade":{"type":"object","properties":{"price":{"type":"number"},"amount":{"type":"number","description":"Stake matched, in dollars. Rounded to the cent."},"traded_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."}},"required":["price","amount","traded_at"],"additionalProperties":false,"description":"The most recent fill on this side."},"lines":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"Identifier for one tradeable line — pass to orders/place and orders/sell. Opaque: its internal composition is not part of this contract and may change. Read it, never build it."},"variable":{"type":"number","description":"The line — a spread, a total, or 0 for a moneyline."},"price":{"type":"number","description":"Taker price as a probability, 0-1. Never American or decimal odds."},"available":{"type":"number","description":"Total amount available on this line across EVERY price, in dollars. Rounded to the cent. Only `top_available` fills at `price`; the rest fills at worse prices (see /markets/depth)."},"top_available":{"type":"number","description":"Amount available at exactly `price` (the top of the book), in dollars. Rounded to the cent. This is what a taker can get at the price shown."}},"required":["order_context_hash","variable","price","available","top_available"],"additionalProperties":false,"description":"One tradeable line, and the hash needed to trade it."},"description":"Every tradeable line. Empty means nobody is offering — you can still post a price."}},"required":["side","side_id","side_type","liquidity","lines"],"additionalProperties":false,"description":"One side of a market, with its depth."},"Liquidity":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"Identifier for one tradeable line — pass to orders/place and orders/sell. Opaque: its internal composition is not part of this contract and may change. Read it, never build it."},"variable":{"type":"number","description":"The line — a spread, a total, or 0 for a moneyline."},"price":{"type":"number","description":"Taker price as a probability, 0-1. Never American or decimal odds."},"available":{"type":"number","description":"Total amount available on this line across EVERY price, in dollars. Rounded to the cent. Only `top_available` fills at `price`; the rest fills at worse prices (see /markets/depth)."},"top_available":{"type":"number","description":"Amount available at exactly `price` (the top of the book), in dollars. Rounded to the cent. This is what a taker can get at the price shown."}},"required":["order_context_hash","variable","price","available","top_available"],"additionalProperties":false,"description":"One tradeable line, and the hash needed to trade it."},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."},"PlacementResponse":{"type":"object","properties":{"placement_status":{"type":"string","enum":["success"],"description":"Always `success` on a 200. A refused order is a 4xx/5xx with an error code (INSUFFICIENT_FUNDS, MARKET_CLOSED, LOCATION_REQUIRED, …) and nothing created or spent."},"message":{"type":"string","description":"Short outcome, safe to log."},"order":{"type":"object","properties":{"order_ids":{"type":"array","items":{"type":"string"},"description":"The order(s) created. A sale that draws on several fills creates one order per fill."},"order_context_hash":{"type":"string"},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Amount submitted, in the unit (dollars for FOR_MONEY, Edge Coins for FREE). Rounded to the cent."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"max_slippage":{"type":"number","description":"How far past `price` this order may fill, in probability points: a buy up to price + max_slippage. 0 for a limit order. Can be less than requested near the top of the book (price + max_slippage is capped at 0.99)."}},"required":["order_ids","order_context_hash","title","price","amount","status","order_type"],"additionalProperties":false,"description":"The order as accepted. Matching happens after acceptance — follow it on the stream or with order activity."}},"required":["placement_status","message","order"],"additionalProperties":false,"description":"An accepted order or sale. Matching happens after acceptance — follow it on the stream or with order activity."},"CancelOrderResponse":{"type":"object","properties":{"order":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size, in the unit. contracts = amount / price. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that matched before the order stopped. Rounded to the cent."},"open_amount":{"type":"number","description":"Part that never filled and was returned. Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount"],"additionalProperties":false,"description":"One order, as of the response."}},"required":["order"],"additionalProperties":false},"BulkCancelResponse":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size, in the unit. contracts = amount / price. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that matched before the order stopped. Rounded to the cent."},"open_amount":{"type":"number","description":"Part that never filled and was returned. Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount"],"additionalProperties":false,"description":"One order, as of the response."},"description":"The orders that were cancelled."}},"required":["orders"],"additionalProperties":false},"Position":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"The selection. Same identifier the board and orders/place use."},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"market_id":{"type":"string"},"side":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"side_id":{"type":"string"},"line":{"type":"number","description":"The spread or total this selection is at; 0 for a moneyline."},"status":{"type":"string","enum":["open","settled"],"description":"`settled` once the selection has been graded. Open positions can still be sold."},"amount":{"type":"number","description":"Stake currently held, at cost. Rounded to the cent."},"invested":{"type":"number","description":"Total stake ever matched on this selection, at cost. Rounded to the cent."},"contracts":{"type":"number","description":"Contracts currently held. Each pays 1 unit if it wins. Six decimal places."},"avg_price":{"type":"number","description":"Blended cost per contract, probability 0-1. 0 when nothing is held."},"potential_payout":{"type":"number","description":"What the held contracts pay if they win. Rounded to the cent."},"cash_from_sales":{"type":"number","description":"Cash already received from selling part of the position. Rounded to the cent."},"working_buy_amount":{"type":"number","description":"Stake resting in unfilled BUY orders on this selection. Not yet a position. Rounded to the cent."},"working_sell_amount":{"type":"number","description":"Cash expected if every resting SELL order on this selection fills. Rounded to the cent."},"result":{"type":"string","enum":["win","lose","draw"],"description":"Present once graded."},"payout":{"type":"number","description":"Settled only: gross amount returned at settlement, before commission. Rounded to the cent."},"net_payout":{"type":"number","description":"Settled only: amount returned at settlement after commission. Rounded to the cent."},"settled_at":{"type":"string","format":"date-time","description":"History only: when the selection settled."},"fills":{"type":"array","items":{"type":"object","properties":{"position_id":{"type":"string","description":"One fill. An order can fill in several parts, each with its own id."},"order_id":{"type":"string","description":"The buy order this fill belongs to."},"price":{"type":"number","description":"Fill price, probability 0-1."},"amount":{"type":"number","description":"Stake matched by this fill, in the unit. Rounded to the cent."},"contracts":{"type":"number","description":"amount / price — what this fill pays if it wins."},"remaining_amount":{"type":"number","description":"Stake from this fill still held (after any sales), at cost. Rounded to the cent."}},"required":["position_id","order_id","price","amount","contracts","remaining_amount"],"additionalProperties":false,"description":"One matched fill on a selection."}}},"required":["order_context_hash","market_type","title","contest_id","contest_type","market_id","side","side_type","side_id","line","status","amount","invested","contracts","avg_price","potential_payout","cash_from_sales","working_buy_amount","working_sell_amount","fills"],"additionalProperties":false,"description":"Everything held on one selection, in one unit."},"Order":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size. For a buy, stake; for a sell, the cash the sale asks for. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that has matched. Rounded to the cent."},"open_amount":{"type":"number","description":"Part still working (or, once cancelled, the part that never filled and was returned). Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."},"collar_pct":{"type":"number","description":"How far past `price` the order may fill, in probability points (the `max_slippage` it was placed with). 0 for a limit."},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"selling_position_id":{"type":"string","description":"Sales only: the fill being sold."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount","collar_pct"],"additionalProperties":false,"description":"One order. contracts = amount / price for buys and sells alike."},"MeResponse":{"type":"object","properties":{"player_id":{"type":"string"},"credential":{"type":"string","enum":["oauth","personal_token"],"description":"Which kind of token this is."},"grant_id":{"type":"string","description":"OAuth only: the player's authorization for your app."},"partner":{"type":"string","description":"OAuth only: your partner slug."},"client":{"type":"object","properties":{"client_id":{"type":"string"},"name":{"type":"string"}},"required":["client_id","name"],"additionalProperties":false,"description":"OAuth only: the app the player approved."},"personal_token_id":{"type":"string","description":"Personal tokens only."},"scopes":{"type":"array","items":{"type":"string","enum":["portfolio:read","orders:write"]},"description":"What the player actually granted — not what was requested."},"expires_at":{"type":"string","format":"date-time","description":"When this token stops working (ISO 8601, UTC): the personal token's expiry, or the OAuth access token's — refresh before it."},"sandbox":{"type":"boolean","description":"Edge Coins only (a sandbox key or sandbox personal token)."},"ip_allowlist":{"type":"array","items":{"type":"string"},"description":"Personal tokens only: the addresses / CIDR ranges the token may be used from."},"terms_current":{"type":"boolean","description":"The player has accepted the current API terms. False → orders are refused with API_TERMS_REQUIRED until they do; reads still work."},"profile":{"type":"object","properties":{"username":{"type":"string","description":"The player's BettorEdge handle."},"verified":{"type":"boolean","description":"Identity verification is complete. Real-money buys need it (else 403 KYC_REQUIRED); Edge Coins do not."}},"required":["username","verified"],"additionalProperties":false,"description":"Present when the token has `portfolio:read`."},"balance":{"type":"object","properties":{"cash":{"type":"object","properties":{"available":{"type":"number","description":"Real-money balance the player can spend right now, in dollars, rounded down to the cent: the balance minus funds already reserved by orders still being placed. The amount an order is checked against."},"currency":{"type":"string","enum":["USD"]}},"required":["available","currency"],"additionalProperties":false},"edge_coins":{"type":"object","properties":{"available":{"type":"number","description":"Edge Coins (play money, `market_type: FREE`) the player can spend right now, on the same rule."}},"required":["available"],"additionalProperties":false}},"required":["cash","edge_coins"],"additionalProperties":false,"description":"Present when the token has `portfolio:read`."}},"required":["player_id","credential","scopes","sandbox"],"additionalProperties":false}}},"security":[{"apiKey":[]}],"paths":{"/v1/your-slug/markets/available":{"get":{"operationId":"listMarkets","summary":"List markets","description":"The main read. Returns contests, each with markets, each with sides, each with the lines you can trade — every line carrying the `order_context_hash` you pass to orders/place. Filter by `league_id` (ids from /leagues) or `event_id`; with neither, returns the most-traded contests across all leagues (up to 25).","tags":["markets"],"security":[{"apiKey":[]},{"personalToken":[]}],"parameters":[{"name":"league_id","in":"query","schema":{"type":"string"},"description":"From /leagues, e.g. `1` (NFL)."},{"name":"event_id","in":"query","schema":{"type":"string"},"description":"One contest."},{"name":"contest_type","in":"query","schema":{"type":"string","enum":["team","tournament","match"]},"description":"With `event_id`. Default `team`."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Page size. Default 50 (10 with no filter, max 25)."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From `next_cursor`."}],"responses":{"200":{"description":"Contests and their depth.","content":{"application/json":{"schema":{"type":"object","properties":{"contests":{"type":"array","items":{"type":"object","properties":{"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"league_id":{"type":"string"},"title":{"type":"string"},"scheduled_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"liquidity":{"type":"number","description":"Sum of available across every market, in dollars. Rounded to the cent."},"volume":{"type":"number","description":"Sum of traded volume across every market, in dollars. Rounded to the cent."},"participants":{"type":"array","items":{"type":"object","properties":{"participant_id":{"type":"string"},"name":{"type":"string"},"alignment":{"type":"string","description":"'home' or 'away' on team contests; absent otherwise."}},"required":["participant_id","name"],"additionalProperties":false,"description":"A team or athlete taking part."}},"markets":{"type":"array","items":{"type":"object","properties":{"market_id":{"type":"string"},"description":{"type":"string","description":"What the market is, e.g. \"Moneyline\" or \"Total Points\"."},"level":{"type":"string","enum":["contest","team","athlete"]},"is_spread_market":{"type":"boolean"},"liquidity":{"type":"number","description":"Sum of available across every side, in dollars. Rounded to the cent."},"volume":{"type":"number","description":"Cumulative traded volume, in dollars. Rounded to the cent."},"sides":{"type":"array","items":{"type":"object","properties":{"side":{"type":"string","description":"Display name of the side."},"side_id":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"best_price":{"type":"number","description":"Best (cheapest) taker price. Absent when nothing is offered on this side."},"liquidity":{"type":"number","description":"Sum of `available` across every line below, in dollars. Rounded to the cent."},"last_trade":{"type":"object","properties":{"price":{"type":"number"},"amount":{"type":"number","description":"Stake matched, in dollars. Rounded to the cent."},"traded_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."}},"required":["price","amount","traded_at"],"additionalProperties":false,"description":"The most recent fill on this side."},"lines":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"Identifier for one tradeable line — pass to orders/place and orders/sell. Opaque: its internal composition is not part of this contract and may change. Read it, never build it."},"variable":{"type":"number","description":"The line — a spread, a total, or 0 for a moneyline."},"price":{"type":"number","description":"Taker price as a probability, 0-1. Never American or decimal odds."},"available":{"type":"number","description":"Total amount available on this line across EVERY price, in dollars. Rounded to the cent. Only `top_available` fills at `price`; the rest fills at worse prices (see /markets/depth)."},"top_available":{"type":"number","description":"Amount available at exactly `price` (the top of the book), in dollars. Rounded to the cent. This is what a taker can get at the price shown."}},"required":["order_context_hash","variable","price","available","top_available"],"additionalProperties":false,"description":"One tradeable line, and the hash needed to trade it."},"description":"Every tradeable line. Empty means nobody is offering — you can still post a price."}},"required":["side","side_id","side_type","liquidity","lines"],"additionalProperties":false,"description":"One side of a market, with its depth."}}},"required":["market_id","description","level","is_spread_market","liquidity","volume","sides"],"additionalProperties":false,"description":"One market on a contest."}}},"required":["contest_id","contest_type","league_id","title","scheduled_at","liquidity","volume","participants","markets"],"additionalProperties":false,"description":"A game, tournament or match, with every market on it."}},"next_cursor":{"type":"string","description":"Opaque. Pass back as `cursor` for the next page. Absent when there are no more."}},"required":["contests"],"additionalProperties":false}}}},"400":{"description":"Invalid `limit`, `cursor` or `contest_type`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `read` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited. Back off using the X-RateLimit-* headers.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Market data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/markets/depth":{"get":{"operationId":"getDepth","summary":"Full price ladder for one line","tags":["markets"],"security":[{"apiKey":[]},{"personalToken":[]}],"parameters":[{"name":"order_context_hash","in":"query","required":true,"schema":{"type":"string"},"description":"From a line in markets/available."}],"responses":{"200":{"description":"Price levels, best first.","content":{"application/json":{"schema":{"type":"object","properties":{"order_context_hash":{"type":"string"},"levels":{"type":"array","items":{"type":"object","properties":{"price":{"type":"number","description":"Taker price as a probability, 0-1."},"available":{"type":"number","description":"Total amount available to take at exactly this price, in dollars. Rounded to the cent."}},"required":["price","available"],"additionalProperties":false,"description":"One price on the ladder. Each price appears once."},"description":"Price levels, best first."}},"required":["order_context_hash","levels"],"additionalProperties":false}}}},"400":{"description":"Missing or malformed order_context_hash.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/orders/place":{"post":{"operationId":"placeOrder","summary":"Place an order","description":"Acts on the account the token belongs to. A 200 means accepted; a refusal is a 4xx/5xx with a code (see Refused orders).","tags":["orders"],"security":[{"apiKey":[],"playerOAuth":["orders:write"]},{"personalToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"From a line in markets/available."},"price":{"type":"number","description":"Probability, 0-1."},"amount":{"type":"number","description":"Dollars to commit. Not a number of contracts."},"expire_time":{"type":"string","description":"Required. When the order stops working, as an ISO 8601 time with a timezone, in the future (e.g. \"2026-10-06T23:00:00Z\"). Missing, unparseable or past → 422 INVALID_EXPIRY.","example":"2026-10-06T23:00:00Z"},"market_type":{"type":"string","enum":["FREE","FOR_MONEY"],"description":"Which balance the order spends: 'FOR_MONEY' (cash) or 'FREE' (Edge Coins, play money). Sandbox keys must send 'FREE' — anything else is refused with SANDBOX_FREE_ONLY."},"order_type":{"type":"string","enum":["limit","market"],"description":"Default 'limit': fills at `price` or better, never worse. 'market': may fill up to `price + max_slippage` (e.g. price 0.53 with max_slippage 0.02 fills at up to 0.55). Either way, whatever does not fill at once keeps working, with the same tolerance, until expire_time — there is no immediate-or-cancel; send a short expire_time to stop an unfilled order quickly."},"max_slippage":{"type":"number","minimum":0,"maximum":0.03,"description":"Required, and greater than 0, when order_type is 'market'; not allowed on a limit order. In probability POINTS on the 0-1 price, not a percentage: 0.02 = 2 cents. At most 0.03. price + max_slippage is capped at 0.99; the response reports the slippage the order actually got. Out of range or missing → 422 VALIDATION_ERROR."}},"required":["order_context_hash","price","amount","expire_time"],"additionalProperties":false,"example":{"order_context_hash":"team:1:1:home:team:2:0","price":0.55,"amount":10,"market_type":"FREE","expire_time":"2026-10-06T23:00:00Z"}},"examples":{"limit":{"summary":"Limit buy (default): fills at 0.53 or better","value":{"order_context_hash":"team:1:1:home:team:2:0","price":0.53,"amount":10,"market_type":"FOR_MONEY","expire_time":"2026-10-06T23:00:00Z"}},"market":{"summary":"Market buy: fills at up to 0.53 + 0.02 = 0.55","value":{"order_context_hash":"team:1:1:home:team:2:0","price":0.53,"amount":10,"market_type":"FOR_MONEY","order_type":"market","max_slippage":0.02,"expire_time":"2026-10-06T23:00:00Z"}}}}}},"responses":{"200":{"description":"Accepted. Matching happens after acceptance — follow it on the stream or with order activity.","headers":{"X-Pulse-Environment":{"description":"'sandbox' for a sandbox key (Edge Coins only), 'production' otherwise.","schema":{"type":"string","enum":["sandbox","production"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"placement_status":{"type":"string","enum":["success"],"description":"Always `success` on a 200. A refused order is a 4xx/5xx with an error code (INSUFFICIENT_FUNDS, MARKET_CLOSED, LOCATION_REQUIRED, …) and nothing created or spent."},"message":{"type":"string","description":"Short outcome, safe to log."},"order":{"type":"object","properties":{"order_ids":{"type":"array","items":{"type":"string"},"description":"The order(s) created. A sale that draws on several fills creates one order per fill."},"order_context_hash":{"type":"string"},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Amount submitted, in the unit (dollars for FOR_MONEY, Edge Coins for FREE). Rounded to the cent."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"max_slippage":{"type":"number","description":"How far past `price` this order may fill, in probability points: a buy up to price + max_slippage. 0 for a limit order. Can be less than requested near the top of the book (price + max_slippage is capped at 0.99)."}},"required":["order_ids","order_context_hash","title","price","amount","status","order_type"],"additionalProperties":false,"description":"The order as accepted. Matching happens after acceptance — follow it on the stream or with order activity."}},"required":["placement_status","message","order"],"additionalProperties":false,"description":"An accepted order or sale. Matching happens after acceptance — follow it on the stream or with order activity."},"examples":{"limit":{"summary":"Limit buy accepted","value":{"placement_status":"success","message":"Order accepted. Follow it on the stream (orders channel) or with order activity.","order":{"order_ids":["5512093"],"order_context_hash":"team:1:1:home:team:2:0","title":"Kansas City Chiefs","price":0.53,"amount":10,"status":"working","order_type":"limit","max_slippage":0}}},"market":{"summary":"Market buy accepted","value":{"placement_status":"success","message":"Order accepted. Follow it on the stream (orders channel) or with order activity.","order":{"order_ids":["5512093"],"order_context_hash":"team:1:1:home:team:2:0","title":"Kansas City Chiefs","price":0.53,"amount":10,"status":"working","order_type":"market","max_slippage":0.02}}}}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `execute` scope; (`SANDBOX_FREE_ONLY`) a sandbox key sent a market_type other than 'FREE', or promo; or the order was refused: `KYC_REQUIRED`, `API_TERMS_REQUIRED`, `LOCATION_REQUIRED`, `LOCATION_NOT_ALLOWED`, `OUTSIDE_US`, `IP_PROXY_DETECTED`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"409":{"description":"`MARKET_CLOSED`: the market is no longer accepting orders.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"422":{"description":"`INSUFFICIENT_FUNDS`, `INVALID_SELECTION`, `INVALID_PRICE`, `INVALID_AMOUNT`, `INVALID_EXPIRY`, `NO_POSITION`, `VALIDATION_ERROR` (order_type / max_slippage) or `ORDER_REJECTED`. Nothing was created or spent.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited, per key or per account — see `limit_scope`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"`UPSTREAM_ERROR`: trading temporarily unavailable; retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"503":{"description":"`BALANCE_UNAVAILABLE` or `LOCATION_CHECK_UNAVAILABLE`: retry after `Retry-After` seconds.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/orders/sell":{"post":{"operationId":"sellPosition","summary":"Sell a position","description":"Acts on the account the token belongs to. Sales are limit-only: `price` is the lowest the sale accepts (selling at 0.53 never fills below 0.53); `order_type: 'market'` or `max_slippage` → 422 `VALIDATION_ERROR`. A 200 means accepted; a refusal is a 4xx/5xx with a code (see Refused orders).","tags":["orders"],"security":[{"apiKey":[],"playerOAuth":["orders:write"]},{"personalToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"The selection you hold, from portfolio/positions."},"price":{"type":"number","description":"Probability, 0-1."},"amount":{"type":"number","description":"Stake to sell, at cost."},"expire_time":{"type":"string","description":"Required. When the sale stops working, as an ISO 8601 time with a timezone, in the future (e.g. \"2026-10-06T23:00:00Z\"). Missing, unparseable or past → 422 INVALID_EXPIRY.","example":"2026-10-06T23:00:00Z"},"order_type":{"type":"string","enum":["limit"],"description":"Sales are limit-only: `price` is the lowest you will accept and the sale never fills below it. order_type 'market' or any max_slippage on a sale → 422 VALIDATION_ERROR. An unfilled remainder keeps working until expire_time."}},"required":["order_context_hash","price","amount","expire_time"],"additionalProperties":false,"example":{"order_context_hash":"team:1:1:home:team:2:0","price":0.6,"amount":5,"expire_time":"2026-10-06T23:00:00Z"}}}}},"responses":{"200":{"description":"Accepted: the sale order(s).","headers":{"X-Pulse-Environment":{"description":"'sandbox' for a sandbox key (Edge Coins only), 'production' otherwise.","schema":{"type":"string","enum":["sandbox","production"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"placement_status":{"type":"string","enum":["success"],"description":"Always `success` on a 200. A refused order is a 4xx/5xx with an error code (INSUFFICIENT_FUNDS, MARKET_CLOSED, LOCATION_REQUIRED, …) and nothing created or spent."},"message":{"type":"string","description":"Short outcome, safe to log."},"order":{"type":"object","properties":{"order_ids":{"type":"array","items":{"type":"string"},"description":"The order(s) created. A sale that draws on several fills creates one order per fill."},"order_context_hash":{"type":"string"},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Amount submitted, in the unit (dollars for FOR_MONEY, Edge Coins for FREE). Rounded to the cent."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"max_slippage":{"type":"number","description":"How far past `price` this order may fill, in probability points: a buy up to price + max_slippage. 0 for a limit order. Can be less than requested near the top of the book (price + max_slippage is capped at 0.99)."}},"required":["order_ids","order_context_hash","title","price","amount","status","order_type"],"additionalProperties":false,"description":"The order as accepted. Matching happens after acceptance — follow it on the stream or with order activity."}},"required":["placement_status","message","order"],"additionalProperties":false,"description":"An accepted order or sale. Matching happens after acceptance — follow it on the stream or with order activity."}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `execute` scope; (`SANDBOX_FREE_ONLY`) a sandbox key tried to sell — sandbox keys cannot sell; or the order was refused: `KYC_REQUIRED`, `API_TERMS_REQUIRED`, `LOCATION_REQUIRED`, `LOCATION_NOT_ALLOWED`, `OUTSIDE_US`, `IP_PROXY_DETECTED`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"409":{"description":"`MARKET_CLOSED`: the market is no longer accepting orders.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"422":{"description":"`INSUFFICIENT_FUNDS`, `INVALID_SELECTION`, `INVALID_PRICE`, `INVALID_AMOUNT`, `INVALID_EXPIRY`, `NO_POSITION`, `VALIDATION_ERROR` (order_type / max_slippage) or `ORDER_REJECTED`. Nothing was created or spent.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited, per key or per account — see `limit_scope`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"`UPSTREAM_ERROR`: trading temporarily unavailable; retry with backoff.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"503":{"description":"`BALANCE_UNAVAILABLE` or `LOCATION_CHECK_UNAVAILABLE`: retry after `Retry-After` seconds.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/orders/cancel":{"post":{"operationId":"cancelOrder","summary":"Cancel an order","description":"Acts on the account the token belongs to.","tags":["orders"],"security":[{"apiKey":[],"playerOAuth":["orders:write"]},{"personalToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"}},"required":["order_id"],"additionalProperties":false}}}},"responses":{"200":{"description":"Cancelled. The order as it stopped, with what had filled.","headers":{"X-Pulse-Environment":{"description":"'sandbox' for a sandbox key (Edge Coins only), 'production' otherwise.","schema":{"type":"string","enum":["sandbox","production"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"order":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size, in the unit. contracts = amount / price. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that matched before the order stopped. Rounded to the cent."},"open_amount":{"type":"number","description":"Part that never filled and was returned. Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount"],"additionalProperties":false,"description":"One order, as of the response."}},"required":["order"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `execute` scope; (`SANDBOX_FREE_ONLY`) a sandbox key targeted an order that is not an Edge Coin ('FREE') order; or the order was refused: `KYC_REQUIRED`, `API_TERMS_REQUIRED`, `LOCATION_REQUIRED`, `LOCATION_NOT_ALLOWED`, `OUTSIDE_US`, `IP_PROXY_DETECTED`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"404":{"description":"`ORDER_NOT_FOUND`: no working order with that id on this account.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited, per key or per account — see `limit_scope`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"`UPSTREAM_ERROR`: trading temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/orders/cancel/bulk":{"post":{"operationId":"bulkCancelOrders","summary":"Cancel several orders","description":"Acts on the account the token belongs to.","tags":["orders"],"security":[{"apiKey":[],"playerOAuth":["orders:write"]},{"personalToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"order_ids":{"type":"array","items":{"type":"string"},"minItems":1,"description":"The orders to cancel. Ids that are not this account's are skipped."}},"required":["order_ids"],"additionalProperties":false}}}},"responses":{"200":{"description":"The orders that were cancelled.","headers":{"X-Pulse-Environment":{"description":"'sandbox' for a sandbox key (Edge Coins only), 'production' otherwise.","schema":{"type":"string","enum":["sandbox","production"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size, in the unit. contracts = amount / price. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that matched before the order stopped. Rounded to the cent."},"open_amount":{"type":"number","description":"Part that never filled and was returned. Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount"],"additionalProperties":false,"description":"One order, as of the response."},"description":"The orders that were cancelled."}},"required":["orders"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `execute` scope; (`SANDBOX_FREE_ONLY`) a sandbox key included an order that is not the account's own Edge Coin ('FREE') order; or the order was refused: `KYC_REQUIRED`, `API_TERMS_REQUIRED`, `LOCATION_REQUIRED`, `LOCATION_NOT_ALLOWED`, `OUTSIDE_US`, `IP_PROXY_DETECTED`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited, per key or per account — see `limit_scope`.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/portfolio/positions":{"get":{"operationId":"listPositions","summary":"List positions","description":"Every selection held or with working orders, in both units unless filtered. Parlays are not represented (`parlays_excluded` counts them). Acts on the account the token belongs to.","tags":["portfolio"],"security":[{"apiKey":[],"playerOAuth":["portfolio:read"]},{"personalToken":[]}],"parameters":[{"name":"market_type","in":"query","schema":{"type":"string","enum":["FOR_MONEY","FREE","all"]},"description":"Filter by unit. Default: both."}],"responses":{"200":{"description":"Positions.","content":{"application/json":{"schema":{"type":"object","properties":{"positions":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"The selection. Same identifier the board and orders/place use."},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"market_id":{"type":"string"},"side":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"side_id":{"type":"string"},"line":{"type":"number","description":"The spread or total this selection is at; 0 for a moneyline."},"status":{"type":"string","enum":["open","settled"],"description":"`settled` once the selection has been graded. Open positions can still be sold."},"amount":{"type":"number","description":"Stake currently held, at cost. Rounded to the cent."},"invested":{"type":"number","description":"Total stake ever matched on this selection, at cost. Rounded to the cent."},"contracts":{"type":"number","description":"Contracts currently held. Each pays 1 unit if it wins. Six decimal places."},"avg_price":{"type":"number","description":"Blended cost per contract, probability 0-1. 0 when nothing is held."},"potential_payout":{"type":"number","description":"What the held contracts pay if they win. Rounded to the cent."},"cash_from_sales":{"type":"number","description":"Cash already received from selling part of the position. Rounded to the cent."},"working_buy_amount":{"type":"number","description":"Stake resting in unfilled BUY orders on this selection. Not yet a position. Rounded to the cent."},"working_sell_amount":{"type":"number","description":"Cash expected if every resting SELL order on this selection fills. Rounded to the cent."},"result":{"type":"string","enum":["win","lose","draw"],"description":"Present once graded."},"payout":{"type":"number","description":"Settled only: gross amount returned at settlement, before commission. Rounded to the cent."},"net_payout":{"type":"number","description":"Settled only: amount returned at settlement after commission. Rounded to the cent."},"settled_at":{"type":"string","format":"date-time","description":"History only: when the selection settled."},"fills":{"type":"array","items":{"type":"object","properties":{"position_id":{"type":"string","description":"One fill. An order can fill in several parts, each with its own id."},"order_id":{"type":"string","description":"The buy order this fill belongs to."},"price":{"type":"number","description":"Fill price, probability 0-1."},"amount":{"type":"number","description":"Stake matched by this fill, in the unit. Rounded to the cent."},"contracts":{"type":"number","description":"amount / price — what this fill pays if it wins."},"remaining_amount":{"type":"number","description":"Stake from this fill still held (after any sales), at cost. Rounded to the cent."}},"required":["position_id","order_id","price","amount","contracts","remaining_amount"],"additionalProperties":false,"description":"One matched fill on a selection."}}},"required":["order_context_hash","market_type","title","contest_id","contest_type","market_id","side","side_type","side_id","line","status","amount","invested","contracts","avg_price","potential_payout","cash_from_sales","working_buy_amount","working_sell_amount","fills"],"additionalProperties":false,"description":"Everything held on one selection, in one unit."}},"parlays_excluded":{"type":"number","description":"Parlays held that this API does not represent. See the docs for why."}},"required":["positions","parlays_excluded"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `read` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Portfolio data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/portfolio/orders":{"get":{"operationId":"listOrders","summary":"List orders","description":"Acts on the account the token belongs to. Working buys and sells, plus buys that filled or were cancelled while their selection is still open. Once a selection settles its orders leave this list — see `portfolio/history`. For any order, `contracts = amount / price`.","tags":["portfolio"],"security":[{"apiKey":[],"playerOAuth":["portfolio:read"]},{"personalToken":[]}],"parameters":[{"name":"market_type","in":"query","schema":{"type":"string","enum":["FOR_MONEY","FREE","all"]},"description":"Filter by unit. Default: both."},{"name":"status","in":"query","schema":{"type":"string","enum":["working","filled","cancelled"]}}],"responses":{"200":{"description":"Orders.","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size. For a buy, stake; for a sell, the cash the sale asks for. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that has matched. Rounded to the cent."},"open_amount":{"type":"number","description":"Part still working (or, once cancelled, the part that never filled and was returned). Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."},"collar_pct":{"type":"number","description":"How far past `price` the order may fill, in probability points (the `max_slippage` it was placed with). 0 for a limit."},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"selling_position_id":{"type":"string","description":"Sales only: the fill being sold."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount","collar_pct"],"additionalProperties":false,"description":"One order. contracts = amount / price for buys and sells alike."}},"parlays_excluded":{"type":"number"}},"required":["orders","parlays_excluded"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `read` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Portfolio data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/portfolio/orders/{order_id}/activity":{"get":{"operationId":"getOrderActivity","summary":"Get order activity","description":"One order's whole life: placement, each fill, expiry, sales, settlement. Acts on the account the token belongs to. Pass a buy or a sale id. A sale resolves to the buy whose position it sold. An order that is not this account's, does not exist, or is not represented by this API (a head-to-head challenge, a parlay leg) is a 404 — the three are deliberately indistinguishable.","tags":["portfolio"],"security":[{"apiKey":[],"playerOAuth":["portfolio:read"]},{"personalToken":[]}],"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The timeline.","content":{"application/json":{"schema":{"type":"object","properties":{"requested_order_id":{"type":"string","description":"The id you asked for. A SALE resolves to the buy whose position it sold, so `order` may be a different order — the timeline tells the whole story either way."},"order_context_hash":{"type":"string"},"order":{"type":"object","properties":{"order_id":{"type":"string"},"order_context_hash":{"type":"string"},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string"},"action":{"type":"string","enum":["buy","sell"],"description":"`sell` is a sale of an existing position."},"order_type":{"type":"string","enum":["limit","market"],"description":"`limit`: fills at `price` or better, never worse. `market`: may fill past `price` by up to its slippage (`collar_pct` here, `max_slippage` when placing) — a buy up to price + slippage. Either way an unfilled remainder keeps working until it expires. Sales are always `limit`."},"status":{"type":"string","enum":["working","filled","cancelled"],"description":"`working` may still fill. `filled` matched in full. `cancelled` stopped working with part or all unfilled — by the account holder, by expiry, or because the contest closed; order activity says which."},"price":{"type":"number","description":"Limit price, probability 0-1."},"amount":{"type":"number","description":"Original size. For a buy, stake; for a sell, the cash the sale asks for. Rounded to the cent."},"filled_amount":{"type":"number","description":"Part of `amount` that has matched. Rounded to the cent."},"open_amount":{"type":"number","description":"Part still working (or, once cancelled, the part that never filled and was returned). Rounded to the cent. On a cancelled or expired order, open_amount is what was still open when it stopped — check status, not open_amount, to know whether it's working."},"collar_pct":{"type":"number","description":"How far past `price` the order may fill, in probability points (the `max_slippage` it was placed with). 0 for a limit."},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"selling_position_id":{"type":"string","description":"Sales only: the fill being sold."}},"required":["order_id","order_context_hash","market_type","title","action","order_type","status","price","amount","filled_amount","open_amount","collar_pct"],"additionalProperties":false,"description":"One order. contracts = amount / price for buys and sells alike."},"position":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"The selection. Same identifier the board and orders/place use."},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"market_id":{"type":"string"},"side":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"side_id":{"type":"string"},"line":{"type":"number","description":"The spread or total this selection is at; 0 for a moneyline."},"status":{"type":"string","enum":["open","settled"],"description":"`settled` once the selection has been graded. Open positions can still be sold."},"amount":{"type":"number","description":"Stake currently held, at cost. Rounded to the cent."},"invested":{"type":"number","description":"Total stake ever matched on this selection, at cost. Rounded to the cent."},"contracts":{"type":"number","description":"Contracts currently held. Each pays 1 unit if it wins. Six decimal places."},"avg_price":{"type":"number","description":"Blended cost per contract, probability 0-1. 0 when nothing is held."},"potential_payout":{"type":"number","description":"What the held contracts pay if they win. Rounded to the cent."},"cash_from_sales":{"type":"number","description":"Cash already received from selling part of the position. Rounded to the cent."},"working_buy_amount":{"type":"number","description":"Stake resting in unfilled BUY orders on this selection. Not yet a position. Rounded to the cent."},"working_sell_amount":{"type":"number","description":"Cash expected if every resting SELL order on this selection fills. Rounded to the cent."},"result":{"type":"string","enum":["win","lose","draw"],"description":"Present once graded."},"payout":{"type":"number","description":"Settled only: gross amount returned at settlement, before commission. Rounded to the cent."},"net_payout":{"type":"number","description":"Settled only: amount returned at settlement after commission. Rounded to the cent."},"settled_at":{"type":"string","format":"date-time","description":"History only: when the selection settled."},"fills":{"type":"array","items":{"type":"object","properties":{"position_id":{"type":"string","description":"One fill. An order can fill in several parts, each with its own id."},"order_id":{"type":"string","description":"The buy order this fill belongs to."},"price":{"type":"number","description":"Fill price, probability 0-1."},"amount":{"type":"number","description":"Stake matched by this fill, in the unit. Rounded to the cent."},"contracts":{"type":"number","description":"amount / price — what this fill pays if it wins."},"remaining_amount":{"type":"number","description":"Stake from this fill still held (after any sales), at cost. Rounded to the cent."}},"required":["position_id","order_id","price","amount","contracts","remaining_amount"],"additionalProperties":false,"description":"One matched fill on a selection."}}},"required":["order_context_hash","market_type","title","contest_id","contest_type","market_id","side","side_type","side_id","line","status","amount","invested","contracts","avg_price","potential_payout","cash_from_sales","working_buy_amount","working_sell_amount","fills"],"additionalProperties":false,"description":"What is held on this selection now.","nullable":true},"activity":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable within a response."},"at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"kind":{"type":"string","enum":["placed","filled","expired","cancelled","sale_placed","sale_filled","sale_cancelled","sale_expired","settled"]},"amount":{"type":"number","description":"Money moved by this event. On `settled`, the net result (negative on a loss). Rounded to the cent."},"contracts":{"type":"number"},"price":{"type":"number","description":"Probability 0-1."},"order_id":{"type":"string"},"position_id":{"type":"string"},"timing":{"type":"string","enum":["exact","approximate"],"description":"Sales and cancellations are only stamped with the row's last update, so their time is approximate. Do not imply more precision than that."}},"required":["id","at","kind","timing"],"additionalProperties":false,"description":"One thing that happened to an order."},"description":"Ascending by time."},"contest":{"type":"object","properties":{"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"title":{"type":"string"},"league_id":{"type":"string"},"scheduled_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"status":{"type":"string","description":"Upstream status string, e.g. scheduled, inprogress, closed."}},"required":["contest_id","contest_type","title"],"additionalProperties":false}},"required":["requested_order_id","order_context_hash","order","position","activity"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `read` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"404":{"description":"Order not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Portfolio data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/portfolio/history":{"get":{"operationId":"listSettledPositions","summary":"List settled positions","description":"Newest first, one unit per call. Acts on the account the token belongs to.","tags":["portfolio"],"security":[{"apiKey":[],"playerOAuth":["portfolio:read"]},{"personalToken":[]}],"parameters":[{"name":"market_type","in":"query","schema":{"type":"string","enum":["FOR_MONEY","FREE"]},"description":"Default FOR_MONEY."},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100},"description":"Default 25."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"From `next_cursor`."}],"responses":{"200":{"description":"A page of settled positions.","content":{"application/json":{"schema":{"type":"object","properties":{"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"positions":{"type":"array","items":{"type":"object","properties":{"order_context_hash":{"type":"string","description":"The selection. Same identifier the board and orders/place use."},"market_type":{"type":"string","enum":["FOR_MONEY","FREE"],"description":"The unit: FOR_MONEY is real dollars, FREE is Edge Coins (play money, the sandbox unit)."},"title":{"type":"string","description":"Human-readable selection, e.g. \"Chiefs -3.5\"."},"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"market_id":{"type":"string"},"side":{"type":"string"},"side_type":{"type":"string","enum":["team","athlete","side"]},"side_id":{"type":"string"},"line":{"type":"number","description":"The spread or total this selection is at; 0 for a moneyline."},"status":{"type":"string","enum":["open","settled"],"description":"`settled` once the selection has been graded. Open positions can still be sold."},"amount":{"type":"number","description":"Stake currently held, at cost. Rounded to the cent."},"invested":{"type":"number","description":"Total stake ever matched on this selection, at cost. Rounded to the cent."},"contracts":{"type":"number","description":"Contracts currently held. Each pays 1 unit if it wins. Six decimal places."},"avg_price":{"type":"number","description":"Blended cost per contract, probability 0-1. 0 when nothing is held."},"potential_payout":{"type":"number","description":"What the held contracts pay if they win. Rounded to the cent."},"cash_from_sales":{"type":"number","description":"Cash already received from selling part of the position. Rounded to the cent."},"working_buy_amount":{"type":"number","description":"Stake resting in unfilled BUY orders on this selection. Not yet a position. Rounded to the cent."},"working_sell_amount":{"type":"number","description":"Cash expected if every resting SELL order on this selection fills. Rounded to the cent."},"result":{"type":"string","enum":["win","lose","draw"],"description":"Present once graded."},"payout":{"type":"number","description":"Settled only: gross amount returned at settlement, before commission. Rounded to the cent."},"net_payout":{"type":"number","description":"Settled only: amount returned at settlement after commission. Rounded to the cent."},"settled_at":{"type":"string","format":"date-time","description":"History only: when the selection settled."},"fills":{"type":"array","items":{"type":"object","properties":{"position_id":{"type":"string","description":"One fill. An order can fill in several parts, each with its own id."},"order_id":{"type":"string","description":"The buy order this fill belongs to."},"price":{"type":"number","description":"Fill price, probability 0-1."},"amount":{"type":"number","description":"Stake matched by this fill, in the unit. Rounded to the cent."},"contracts":{"type":"number","description":"amount / price — what this fill pays if it wins."},"remaining_amount":{"type":"number","description":"Stake from this fill still held (after any sales), at cost. Rounded to the cent."}},"required":["position_id","order_id","price","amount","contracts","remaining_amount"],"additionalProperties":false,"description":"One matched fill on a selection."}}},"required":["order_context_hash","market_type","title","contest_id","contest_type","market_id","side","side_type","side_id","line","status","amount","invested","contracts","avg_price","potential_payout","cash_from_sales","working_buy_amount","working_sell_amount","fills"],"additionalProperties":false,"description":"Everything held on one selection, in one unit."},"description":"Settled selections, newest first."},"next_cursor":{"type":"string","description":"Opaque. Pass back as `cursor` for the next page. Absent when there are no more."},"total":{"type":"number","description":"Settled selections in the requested range."}},"required":["market_type","positions","total"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid credentials.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Key lacks the `read` scope.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Portfolio data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/markets/history":{"get":{"operationId":"getTradeHistory","summary":"Price history for one line","description":"Raw prints or OHLC candles, plus the closing line. Public market data.","tags":["markets"],"security":[{"apiKey":[]},{"personalToken":[]}],"parameters":[{"name":"order_context_hash","in":"query","required":true,"schema":{"type":"string"},"description":"From a line in markets/available."},{"name":"interval","in":"query","schema":{"type":"string","enum":["raw","1m","5m","15m","1h","1d"]},"description":"Default raw."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"before","in":"query","schema":{"type":"string","format":"date-time"},"description":"From `next_before`."}],"responses":{"200":{"description":"Price history.","content":{"application/json":{"schema":{"type":"object","properties":{"order_context_hash":{"type":"string"},"interval":{"type":"string","enum":["raw","1m","5m","15m","1h","1d"]},"points":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"price":{"type":"number","description":"Probability 0-1 for the requested side."},"amount":{"type":"number","description":"Stake matched on this print, in dollars. Rounded to the cent."}},"required":["at","price","amount"],"additionalProperties":false},"description":"Present when interval=raw. Newest last."},"candles":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Bucket start."},"open":{"type":"number"},"high":{"type":"number"},"low":{"type":"number"},"close":{"type":"number"},"volume":{"type":"number"},"trades":{"type":"number"}},"required":["at","open","high","low","close","volume","trades"],"additionalProperties":false},"description":"Present for any other interval."},"summary":{"type":"object","properties":{"first":{"type":"number"},"last":{"type":"number"},"high":{"type":"number"},"low":{"type":"number"},"change":{"type":"number","description":"last - first, in probability points."},"volume":{"type":"number"},"trades":{"type":"number"}},"required":["volume","trades"],"additionalProperties":false},"closing":{"type":"object","properties":{"price":{"type":"number"},"line":{"type":"number","description":"The line that closed, in the requested side's frame."},"at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"amount":{"type":"number"}},"required":["price","line","at","amount"],"additionalProperties":false,"description":"The last print before the contest started. Absent before then, or if nothing traded."},"next_before":{"type":"string","description":"Pass back as `before` for older history."}},"required":["order_context_hash","interval","summary"],"additionalProperties":false}}}},"400":{"description":"Missing or malformed parameter.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Market data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/contests":{"get":{"operationId":"lookupContests","summary":"Look up contests","description":"Names, start times, status and participants for ids you hold from positions, orders or stream events — including contests that have finished and left the board. Up to 50 refs per call.","tags":["reference"],"security":[{"apiKey":[]},{"personalToken":[]}],"parameters":[{"name":"ids","in":"query","required":true,"schema":{"type":"string"},"description":"Comma-separated `<contest_type>:<contest_id>`, e.g. `team:123,match:45`."}],"responses":{"200":{"description":"Found contests, and the refs that were not.","content":{"application/json":{"schema":{"type":"object","properties":{"contests":{"type":"array","items":{"type":"object","properties":{"contest_id":{"type":"string"},"contest_type":{"type":"string","enum":["team","tournament","match"]},"title":{"type":"string"},"league_id":{"type":"string"},"scheduled_at":{"type":"string","format":"date-time","description":"ISO 8601, UTC."},"status":{"type":"string","description":"Upstream status string, e.g. scheduled, inprogress, closed."},"participants":{"type":"array","items":{"type":"object","properties":{"participant_id":{"type":"string"},"name":{"type":"string"},"abbr":{"type":"string"},"alignment":{"type":"string","enum":["home","away"]},"score":{"type":"number"}},"required":["participant_id","name"],"additionalProperties":false},"description":"Home and away on team contests; empty otherwise."}},"required":["contest_id","contest_type","title","participants"],"additionalProperties":false}},"not_found":{"type":"array","items":{"type":"string"},"description":"Refs you asked for that do not exist, as `type:id`."}},"required":["contests","not_found"],"additionalProperties":false}}}},"400":{"description":"Malformed ids.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"502":{"description":"Contest data temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/leagues":{"get":{"operationId":"listLeagues","summary":"List leagues","description":"League ids and names — pass an id as `league_id` to markets/available.","tags":["reference"],"security":[{"apiKey":[]},{"personalToken":[]}],"responses":{"200":{"description":"Leagues.","content":{"application/json":{"schema":{"type":"object","properties":{"leagues":{"type":"array","items":{"type":"object","properties":{"league_id":{"type":"string"},"name":{"type":"string"},"sport":{"type":"string"},"status":{"type":"string"}},"required":["league_id","name"],"additionalProperties":false}}},"required":["leagues"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/v1/your-slug/me":{"get":{"operationId":"whoAmI","summary":"Check a token, profile and balance","description":"Which account a token acts for and what it may do: the scopes actually granted, when the token expires, whether it is sandbox (Edge Coins only) and whether the player has accepted the current API terms. Partner (OAuth) tokens also name the app and partner; personal tokens their IP allowlist.\n\nWith `portfolio:read`, also the basic `profile` (`username` and `verified` — whether real-money buys are possible) and the spendable `balance`: `cash.available` in dollars and `edge_coins.available`, each the balance minus funds already reserved by orders still being placed, rounded down to the cent. Without `portfolio:read` both are absent. Payment methods, bank details, deposits and withdrawals are never available through this API. Acts on the account the token belongs to.","tags":["auth"],"security":[{"apiKey":[],"playerOAuth":[]},{"personalToken":[]}],"responses":{"200":{"description":"The player, the credential, and (with portfolio:read) profile and balance.","content":{"application/json":{"schema":{"type":"object","properties":{"player_id":{"type":"string"},"credential":{"type":"string","enum":["oauth","personal_token"],"description":"Which kind of token this is."},"grant_id":{"type":"string","description":"OAuth only: the player's authorization for your app."},"partner":{"type":"string","description":"OAuth only: your partner slug."},"client":{"type":"object","properties":{"client_id":{"type":"string"},"name":{"type":"string"}},"required":["client_id","name"],"additionalProperties":false,"description":"OAuth only: the app the player approved."},"personal_token_id":{"type":"string","description":"Personal tokens only."},"scopes":{"type":"array","items":{"type":"string","enum":["portfolio:read","orders:write"]},"description":"What the player actually granted — not what was requested."},"expires_at":{"type":"string","format":"date-time","description":"When this token stops working (ISO 8601, UTC): the personal token's expiry, or the OAuth access token's — refresh before it."},"sandbox":{"type":"boolean","description":"Edge Coins only (a sandbox key or sandbox personal token)."},"ip_allowlist":{"type":"array","items":{"type":"string"},"description":"Personal tokens only: the addresses / CIDR ranges the token may be used from."},"terms_current":{"type":"boolean","description":"The player has accepted the current API terms. False → orders are refused with API_TERMS_REQUIRED until they do; reads still work."},"profile":{"type":"object","properties":{"username":{"type":"string","description":"The player's BettorEdge handle."},"verified":{"type":"boolean","description":"Identity verification is complete. Real-money buys need it (else 403 KYC_REQUIRED); Edge Coins do not."}},"required":["username","verified"],"additionalProperties":false,"description":"Present when the token has `portfolio:read`."},"balance":{"type":"object","properties":{"cash":{"type":"object","properties":{"available":{"type":"number","description":"Real-money balance the player can spend right now, in dollars, rounded down to the cent: the balance minus funds already reserved by orders still being placed. The amount an order is checked against."},"currency":{"type":"string","enum":["USD"]}},"required":["available","currency"],"additionalProperties":false},"edge_coins":{"type":"object","properties":{"available":{"type":"number","description":"Edge Coins (play money, `market_type: FREE`) the player can spend right now, on the same rule."}},"required":["available"],"additionalProperties":false}},"required":["cash","edge_coins"],"additionalProperties":false,"description":"Present when the token has `portfolio:read`."}},"required":["player_id","credential","scopes","sandbox"],"additionalProperties":false,"example":{"player_id":"48213","credential":"personal_token","personal_token_id":"6f1c2a9e-3b7d-4c11-9a52-0d8e4f7b2c90","scopes":["portfolio:read","orders:write"],"expires_at":"2027-01-04T17:00:00.000Z","sandbox":false,"ip_allowlist":["203.0.113.7","198.51.100.0/24"],"terms_current":true,"profile":{"username":"sharpbettor","verified":true},"balance":{"cash":{"available":182.4,"currency":"USD"},"edge_coins":{"available":9500}}}}}}},"401":{"description":"`INVALID_BEARER`: the token is invalid, expired or revoked. `MISSING_API_KEY`: no credential at all.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"403":{"description":"Token issued to another partner (PARTNER_MISMATCH), or IP not on a personal token's allowlist.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}},"503":{"description":"The authorization or the account could not be checked right now. Retry.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["MISSING_API_KEY","INVALID_API_KEY","KEY_SUSPENDED","BRAND_MISMATCH","MISSING_BEARER","INVALID_BEARER","INSUFFICIENT_SCOPE","SANDBOX_FREE_ONLY","RATE_LIMITED","UPSTREAM_ERROR","VALIDATION_ERROR","NOT_FOUND","INTERNAL_ERROR","PARTNER_MISMATCH","IP_NOT_ALLOWED","INSUFFICIENT_FUNDS","BALANCE_UNAVAILABLE","MARKET_CLOSED","INVALID_SELECTION","INVALID_PRICE","INVALID_AMOUNT","INVALID_EXPIRY","NO_POSITION","KYC_REQUIRED","API_TERMS_REQUIRED","LOCATION_REQUIRED","LOCATION_NOT_ALLOWED","OUTSIDE_US","IP_PROXY_DETECTED","LOCATION_CHECK_UNAVAILABLE","ORDER_NOT_FOUND","ORDER_REJECTED"]},"message":{"type":"string"},"request_id":{"type":"string","description":"Include this when reporting a problem — it is logged on our side."}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false,"description":"Every error from this API has this shape."}}}}}}},"/oauth/token":{"servers":[{"url":"https://pulse.bettoredge.com"}],"post":{"operationId":"oauthToken","summary":"Exchange an authorization code, or refresh (partners)","tags":["auth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"grant_type":{"type":"string","enum":["authorization_code","refresh_token"]},"code":{"type":"string"},"redirect_uri":{"type":"string"},"code_verifier":{"type":"string"},"refresh_token":{"type":"string"},"scope":{"type":"string","description":"Refresh only: narrow this access token. Never widens."},"client_id":{"type":"string","description":"Public clients, or client_secret_post."},"client_secret":{"type":"string","description":"client_secret_post. Prefer HTTP Basic."}},"required":["grant_type"]}}}},"responses":{"200":{"description":"Tokens. The refresh token is new on every call; the old one is now retired.","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"expires_in":{"type":"integer"},"refresh_token":{"type":"string"},"scope":{"type":"string"}},"required":["access_token","token_type","expires_in","refresh_token","scope"]}}}},"400":{"description":"invalid_request, invalid_grant, invalid_scope or unsupported_grant_type.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"}},"required":["error"]}}}},"401":{"description":"invalid_client.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"}},"required":["error"]}}}}}}},"/oauth/revoke":{"servers":[{"url":"https://pulse.bettoredge.com"}],"post":{"operationId":"oauthRevoke","summary":"Revoke a player token (partners, RFC 7009)","description":"Revoking either token revokes the player's whole authorization for your app.","tags":["auth"],"security":[],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]}}}},"responses":{"200":{"description":"Revoked, or nothing to revoke."},"401":{"description":"invalid_client.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"}},"required":["error"]}}}}}}}}}