{"format":"opendoc-document","version":1,"url":"https://docs.upscale.trade/developers","title":"Upscale Public API","description":"Programmatic access to Upscale trading with a personal API key. Only the endpoints listed here accept an API key — everything else requires an interactive…","kind":"api-overview","locale":"en","inLanguage":"en","lastModified":"2026-09-28T19:22:49.100Z","revision":"25c86f549328fcff320805d5945f4c9804e3927950d831e601d6e3b18c170f66","section":{"title":"Developers","url":"https://docs.upscale.trade/developers"},"representations":{"html":"https://docs.upscale.trade/developers","markdown":"https://docs.upscale.trade/developers.md","json":"https://docs.upscale.trade/developers.json"},"translations":{"en":"https://docs.upscale.trade/developers","ru":"https://docs.upscale.trade/ru/developers","es":"https://docs.upscale.trade/es/developers"},"breadcrumbs":[{"title":"What is Prop Trading","url":"https://docs.upscale.trade"},{"title":"Upscale Public API","url":"https://docs.upscale.trade/developers"}],"headings":[{"depth":2,"id":"quick-start","title":"Quick start"},{"depth":3,"id":"javascript-node-18","title":"JavaScript (Node 18+)"},{"depth":3,"id":"python-3-10","title":"Python (3.10+)"},{"depth":3,"id":"where-to-go-next","title":"Where to go next"},{"depth":2,"id":"authentication","title":"Authentication"},{"depth":2,"id":"conventions","title":"Conventions"},{"depth":2,"id":"rate-limits","title":"Rate limits"},{"depth":2,"id":"errors","title":"Errors"},{"depth":2,"id":"operations","title":"Operations"}],"markdown":"---\ntitle: Upscale Public API\nicon: book-open\napiVersion: d796ac9\n---\n\nProgrammatic access to Upscale trading with a personal API key.\nOnly the endpoints listed here accept an API key — everything else requires an interactive session.\n\n## Quick start\n\nOpening and closing a position takes five calls. Everything below runs against `https://api.upscale.trade` with a single\npersonal API key in the `Authorization` header — see [Authentication](/developers#authentication) for how to get one.\n\n| # | Call | What it gives you |\n|---|------|-------------------|\n| 1 | `GET /accounts/with-risk-status` | The accounts the key may trade, each with its phase, status, balance and equity. Take `accountId` from the one to trade on. |\n| 2 | `GET /v2/markets?accountId=…` | The tradable markets with the price, fees and leverage bounds an order on that account is checked against. Take `id` of the market. |\n| 3 | `POST /orders` with `type: \"market\"` | Opens the position. `amount` is the quote reserve to spend, `leverage` the multiplier. |\n| 4 | `GET /positions/{accountId}/active` | The open positions. Needed because the order response carries no position identifier. |\n| 5 | `POST /orders` with `type: \"take\"` and `triggerPrice: \"0\"` | Closes that position at market. `amount` is the base size to close. |\n\nThree things to settle before writing any code:\n\n- **Every number is an fp9 raw string** — the value scaled by 10⁹. 100 USD is `\"100000000000\"`, 10x leverage is\n  `\"10000000000\"`. Read and write them with `BigInt` / `Decimal`; a float silently rounds away the last digits.\n- **`amount` changes unit with the order class.** On the `market` order that opens a position it is a **quote**\n  amount — margin, fee, spread and buffer reserved from the free balance. On the `take` order that closes it,\n  it is the **base asset** size of the position, and nothing is reserved. Step 5 passes the position `size` straight through.\n- **Closing is a `take` order, not a market order the other way.** Positions are held per direction, so a `short`\n  market order placed against an open `long` opens a second position instead of closing the first. A `take` with\n  `triggerPrice: \"0\"` carries no trigger and fills at market while the call is still open; an `amount` larger than\n  the position holds closes it in full. To flatten an account in one call use `POST /positions/{accountId}/close-all`.\n\nBoth scripts below are complete: set `UPSCALE_API_KEY` in the environment and run.\n\n### JavaScript (Node 18+)\n\nSave as `upscale.mjs` and run with `node upscale.mjs` — no dependencies.\n\n```js\nimport { randomUUID } from 'node:crypto';\n\nconst BASE_URL = 'https://api.upscale.trade';\nconst API_KEY = process.env.UPSCALE_API_KEY;\n\n// Human decimal -> fp9 raw string: 100 -> \"100000000000\", \"0.5\" -> \"500000000\".\nconst toFp9 = (value) => {\n  const [whole, fraction = ''] = String(value).split('.');\n  return BigInt(whole + fraction.padEnd(9, '0').slice(0, 9)).toString();\n};\n\n// fp9 raw string -> human decimal string. Stays on BigInt: Number loses the low digits above ~9M USD.\nconst fromFp9 = (raw) => {\n  const negative = raw.startsWith('-');\n  const digits = (negative ? raw.slice(1) : raw).padStart(10, '0');\n  return `${negative ? '-' : ''}${digits.slice(0, -9)}.${digits.slice(-9)}`;\n};\n\nconst call = async (method, path, body) => {\n  const response = await fetch(`${BASE_URL}${path}`, {\n    method,\n    headers: {\n      Authorization: `Bearer ${API_KEY}`,\n      // One key per logical request; a retry of that request must send the same key again.\n      ...(body ? { 'Content-Type': 'application/json', 'x-idempotency-key': randomUUID() } : {}),\n    },\n    body: body ? JSON.stringify(body) : undefined,\n  });\n  const payload = response.status === 204 ? null : await response.json();\n  if (!response.ok) {\n    // `error` is the stable machine-readable code — branch on it, never on `message`.\n    throw new Error(`${method} ${path} -> ${response.status} ${payload?.error}: ${payload?.message}`);\n  }\n  return payload;\n};\n\n// 1. Accounts. Authenticated with an API key the list holds only accounts that have api_trading enabled.\nconst accounts = await call('GET', '/accounts/with-risk-status');\nconst account = accounts.find((item) => item.status === 'active' && item.apiTrading && item.type === 'demo');\nif (!account) {\n  throw new Error('No active demo account with API trading enabled');\n}\nconsole.log(`account ${account.accountId}, equity ${fromFp9(account.riskStatus.currentEquity)}`);\n\n// 2. Markets, priced by the shard that hosts this account — the state the order will be filled against.\nconst markets = await call('GET', `/v2/markets?accountId=${account.accountId}`);\nconst market = markets.find((item) => item.config.baseAsset === 'BTC');\nif (!market) {\n  throw new Error('BTC is not available on this account');\n}\nconsole.log(`${market.config.ticker} at ${fromFp9(market.state.indexPrice)}`);\n\n// 3. Open a long: 100 USD of reserve at 10x, filled at market.\nconst order = await call('POST', '/orders', {\n  accountId: account.accountId,\n  marketId: market.id,\n  type: 'market',\n  direction: 'long',\n  amount: toFp9(100),\n  leverage: toFp9(10),\n  expectedAmount: '0', // no slippage check; pass the base size you expect to enforce one\n});\nconsole.log(`order ${order.id} ${order.status}`);\n\n// 4. Read the position back — the order response does not carry its identifier.\nconst positions = await call('GET', `/positions/${account.accountId}/active`);\nconst position = positions.find((item) => item.market === market.id && item.direction === 'long');\nif (!position) {\n  throw new Error('Position not found — the order may have been deferred or rejected at execution');\n}\nconsole.log(`position ${position.idx}, size ${fromFp9(position.size)} ${market.config.baseAsset}`);\n\n// 5. Close it at market.\nawait call('POST', '/orders', {\n  accountId: account.accountId,\n  marketId: market.id,\n  type: 'take',\n  direction: position.direction, // a close order runs in the same direction as its position\n  positionId: position.idx,\n  amount: position.size, // base units\n  triggerPrice: '0', // no trigger: fill now\n});\nconsole.log('closed');\n```\n\n### Python (3.10+)\n\nNeeds `requests` (`pip install requests`).\n\n```python\nimport os\nimport uuid\nfrom decimal import Decimal\n\nimport requests\n\nBASE_URL = 'https://api.upscale.trade'\nAPI_KEY = os.environ['UPSCALE_API_KEY']\nFP9 = Decimal(10) ** 9\n\n\ndef to_fp9(value) -> str:\n    \"\"\"Human decimal -> fp9 raw string: 100 -> \"100000000000\".\"\"\"\n    return str(int(Decimal(str(value)) * FP9))\n\n\ndef from_fp9(raw: str) -> Decimal:\n    \"\"\"fp9 raw string -> Decimal. Never float — it drops the low digits.\"\"\"\n    return Decimal(raw) / FP9\n\n\ndef call(method: str, path: str, body: dict | None = None):\n    headers = {'Authorization': f'Bearer {API_KEY}'}\n    if body is not None:\n        # One key per logical request; a retry of that request must send the same key again.\n        headers['x-idempotency-key'] = str(uuid.uuid4())\n    response = requests.request(method, f'{BASE_URL}{path}', json=body, headers=headers, timeout=30)\n    payload = None if response.status_code == 204 else response.json()\n    if not response.ok:\n        # `error` is the stable machine-readable code — branch on it, never on `message`.\n        raise RuntimeError(\n            f'{method} {path} -> {response.status_code} {payload.get(\"error\")}: {payload.get(\"message\")}'\n        )\n    return payload\n\n\n# 1. Accounts. Authenticated with an API key the list holds only accounts that have api_trading enabled.\naccounts = call('GET', '/accounts/with-risk-status')\naccount = next((item for item in accounts if item['status'] == 'active' and item['apiTrading'] and item['type'] == 'demo'), None)\nif account is None:\n    raise SystemExit('No active demo account with API trading enabled')\nprint(f\"account {account['accountId']}, equity {from_fp9(account['riskStatus']['currentEquity'])}\")\n\n# 2. Markets, priced by the shard that hosts this account — the state the order will be filled against.\nmarkets = call('GET', f\"/v2/markets?accountId={account['accountId']}\")\nmarket = next((item for item in markets if item['config']['baseAsset'] == 'BTC'), None)\nif market is None:\n    raise SystemExit('BTC is not available on this account')\nprint(f\"{market['config']['ticker']} at {from_fp9(market['state']['indexPrice'])}\")\n\n# 3. Open a long: 100 USD of reserve at 10x, filled at market.\norder = call('POST', '/orders', {\n    'accountId': account['accountId'],\n    'marketId': market['id'],\n    'type': 'market',\n    'direction': 'long',\n    'amount': to_fp9(100),\n    'leverage': to_fp9(10),\n    'expectedAmount': '0',  # no slippage check; pass the base size you expect to enforce one\n})\nprint(f\"order {order['id']} {order['status']}\")\n\n# 4. Read the position back — the order response does not carry its identifier.\npositions = call('GET', f\"/positions/{account['accountId']}/active\")\nposition = next((item for item in positions if item['market'] == market['id'] and item['direction'] == 'long'), None)\nif position is None:\n    raise SystemExit('Position not found — the order may have been deferred or rejected at execution')\nprint(f\"position {position['idx']}, size {from_fp9(position['size'])} {market['config']['baseAsset']}\")\n\n# 5. Close it at market.\ncall('POST', '/orders', {\n    'accountId': account['accountId'],\n    'marketId': market['id'],\n    'type': 'take',\n    'direction': position['direction'],  # a close order runs in the same direction as its position\n    'positionId': position['idx'],\n    'amount': position['size'],  # base units\n    'triggerPrice': '0',  # no trigger: fill now\n})\nprint('closed')\n```\n\n### Where to go next\n\n- Deferred entries (`limit`, `stop_market`, `stop_limit`) and protective orders (`stop`, `trailing_stop`) take the same\n  `POST /orders` route — the operation lists what each type requires.\n- A stop-loss and a take-profit can ride along with the opening order as `stopTriggerPrice` and `takeTriggerPrice`.\n- `GET /accounts/{accountId}/risk-status` is the endpoint to poll for drawdown headroom while a position is open.\n\n\n## Authentication\n\nCreate a key in the Upscale app (or with `POST /user/api-keys` from an authenticated session) — the raw key\nis shown once, at creation time. Pass it as a bearer token:\n\n```\nAuthorization: Bearer usk_<your key>\n```\n\nA key inherits the permissions of the user it belongs to and stays valid until it is deleted, refreshed or expires.\n\nTrading over the API is enabled per account: an account with `api_trading` turned off answers `403`\n(`api_trading_not_enabled`) to every request made with a key, and account lists leave it out entirely.\n\n## Conventions\n\n- Amounts, prices, leverage and multipliers travel as **fp9 raw integer strings** — the value scaled by 10⁹.\n  `\"1000000000\"` is 1 USD, `\"10000000000\"` is 10x leverage, `\"50000000\"` is 5%.\n- fp9 fixes the scale, not the unit. A quote amount is USD; a base size is units of the traded asset. `amount` on an order is\n  quote on increase orders and base on close orders — every field says which of the two it carries.\n- Identifiers are uuid v4. Markets are addressed by identifier when trading and by base asset ticker\n  (`BTC`) on the per-market read endpoints.\n- Lists page through `limit` and `offset` and return the total count next to the page.\n- Positions and orders are scoped to the phase the account is in right now: what belongs to a finished\n  phase is no longer returned.\n\n## Rate limits\n\nLimits are counted per key, in fixed windows, separately for read (GET) and write (everything else) endpoints.\nDefaults are 10 requests per second and 60 per minute\nfor reads, 10 per second and 60 per minute for writes.\n\nExceeding a limit returns `429` (`api_key_rate_limit_exceeded`) with a `Retry-After` header and a body\ncarrying the bucket (`read` / `write`), the window that tripped, its limit and `retryAt`.\n\nThe key's own limits are the only ones a key is subject to. The per-endpoint limits the Upscale app runs into\nare counted per interactive session and are not applied to API-key requests, so no endpoint here carries a\ntighter limit of its own.\n\n## Errors\n\nA failure answers with `{ statusCode, message, error }`, where `error` is a stable machine-readable code.\nBranch on that code, not on the message text.\n\n- `400` — the body, query or path failed schema validation (`validation_failed`), or a trading precondition\n  was rejected (`insufficient_balance`, `position_not_available`, and the per-operation codes below).\n- `401` — the key is missing, malformed, revoked or expired (`session_expired`).\n- `403` — the key was used on an endpoint that does not accept keys (`api_key_not_allowed`), the account belongs\n  to someone else (`account_access_denied`), API trading is off (`api_trading_not_enabled`), the account is no\n  longer trading (`challenge_closed`), has not reached a tradable phase (`account_phase_not_allowed`) or is locked\n  by the managed capital limit (`funded_limit_trading_locked`), the order is no longer active\n  (`order_not_active`), or the market is paused (`market_paused`), close-only (`market_close_only`) or outside\n  the category the account may trade (`market_category_not_allowed`).\n- `404` — no such account (`account_not_found`), order (`order_not_found`), position (`position_not_found`)\n  or market (`market_not_found`).\n- `409` — a request with the same `x-idempotency-key` is still being processed (`idempotency_key_in_flight`),\n  the account is not currently loaded by the trading engine (`account_not_loaded`), or the market price has not\n  been updated recently enough to trade on (`market_price_stale`).\n- `429` — the rate limit of the key tripped (`api_key_rate_limit_exceeded`).\n\nOrder-level rejections come back as `400` with a code naming the field combination at fault; each trading\noperation lists the ones it can produce.\n\n\n## Operations\n\n- [GET /accounts/{accountId}/equity-history — Get the equity history of the trader account](/developers/operations/getaccountequityhistory)\n\n- [GET /accounts/{accountId}/risk-status — Get the risk status of the trader account](/developers/operations/getaccountriskstatus)\n\n- [GET /accounts/{accountId}/stats — Get trading stats of the trader account](/developers/operations/getaccounttradingstats)\n\n- [POST /accounts/{accountId}/close-all — Close all positions and orders](/developers/operations/closeallpositionsandorders)\n\n- [GET /accounts/events — Get the events of the trader account](/developers/operations/getaccountsevents)\n\n- [GET /accounts/risk-status — Get all accounts of current user risk status](/developers/operations/getaccountsriskstatus)\n\n- [GET /accounts/with-risk-status — Get all accounts of current user with risk status](/developers/operations/getaccountswithriskstatus)\n\n- [GET /v2/markets — Get markets list](/developers/operations/getmarkets)\n\n- [GET /v2/markets/{id} — Get market by id](/developers/operations/getmarket)\n\n- [POST /orders — Create new order](/developers/operations/createorder)\n\n- [POST /orders/{accountId}/close-all — Close all orders](/developers/operations/closeallorders)\n\n- [GET /orders/{accountId}/active — Get all active orders](/developers/operations/getactiveorders)\n\n- [GET /orders/{accountId}/{asset}/active — Get active orders by ticker](/developers/operations/getactiveordersbyticker)\n\n- [GET /orders/{accountId}/{asset}/history — Get orders history by ticker](/developers/operations/getordershistorybyticker)\n\n- [PATCH /orders/{orderId} — Change order trigger price](/developers/operations/updateorder)\n\n- [DELETE /orders/{orderId} — Cancel order](/developers/operations/cancelorder)\n\n- [GET /positions/{accountId}/active — Get all active positions](/developers/operations/getactivepositions)\n\n- [GET /positions/{accountId}/portfolio/history — Get all positions history](/developers/operations/getpositionshistory)\n\n- [GET /positions/{positionId}/history — Get all events by position](/developers/operations/getpositionevents)\n\n- [GET /positions/{positionId} — Get position details](/developers/operations/getposition)\n\n- [PATCH /positions/{positionId}/margin — Change position margin](/developers/operations/changemargin)\n\n- [POST /positions/{accountId}/close-all — Close all positions](/developers/operations/closeallpositions)\n\n- [GET /positions/{accountId}/{asset}/history — Get positions history by ticker](/developers/operations/getpositionshistorybyticker)\n\n- [GET /positions/{accountId}/{asset}/active — Get active positions by ticker](/developers/operations/getactivepositionsbyticker)\n\n- [GET /positions/{accountId}/{asset}/open-notional — Get current open interest by ticker](/developers/operations/getopennotionalbyticker)\n\n- [GET /positions/{accountId}/{asset}/chart-events — Get position events for chart indicators by ticker](/developers/operations/getchartevents)\n\n- [GET /positions/{accountId}/{asset}/chart-events/buckets — Get position events for chart indicators grouped by candles](/developers/operations/getcharteventbuckets)\n\n- [GET /positions/{accountId}/{asset}/scalping-coefficient — Get scalping coefficient for ticker](/developers/operations/getscalpingcoefficient)","text":"Programmatic access to Upscale trading with a personal API key. Only the endpoints listed here accept an API key — everything else requires an interactive session. Quick start Opening and closing a position takes five calls. Everything below runs against https://api.upscale.trade with a single personal API key in the Authorization header — see Authentication for how to get one. Call What it gives you 1 GET /accounts/with risk status The accounts the key may trade, each with its phase, status, balance and equity. Take accountId from the one to trade on. 2 GET /v2/markets?accountId=… The tradable markets with the price, fees and leverage bounds an order on that account is checked against. Take id of the market. 3 POST /orders with type: \"market\" Opens the position. amount is the quote reserve to spend, leverage the multiplier. 4 GET /positions/{accountId}/active The open positions. Needed because the order response carries no position identifier. 5 POST /orders with type: \"take\" and triggerPrice: \"0\" Closes that position at market. amount is the base size to close. Three things to settle before writing any code: Every number is an fp9 raw string — the value scaled by 10⁹. 100 USD is \"100000000000\" , 10x leverage is \"10000000000\" . Read and write them with BigInt / Decimal ; a float silently rounds away the last digits. amount changes unit with the order class. On the market order that opens a position it is a quote amount — margin, fee, spread and buffer reserved from the free balance. On the take order that closes it, it is the base asset size of the position, and nothing is reserved. Step 5 passes the position size straight through. Closing is a take order, not a market order the other way. Positions are held per direction, so a short market order placed against an open long opens a second position instead of closing the first. A take with triggerPrice: \"0\" carries no trigger and fills at market while the call is still open; an amount larger than the position holds closes it in full. To flatten an account in one call use POST /positions/{accountId}/close all . Both scripts below are complete: set UPSCALE API KEY in the environment and run. JavaScript (Node 18+) Save as upscale.mjs and run with node upscale.mjs — no dependencies. Python (3.10+) Needs requests ( pip install requests ). Where to go next Deferred entries ( limit , stop market , stop limit ) and protective orders ( stop , trailing stop ) take the same POST /orders route — the operation lists what each type requires. A stop loss and a take profit can ride along with the opening order as stopTriggerPrice and takeTriggerPrice . GET /accounts/{accountId}/risk status is the endpoint to poll for drawdown headroom while a position is open. Authentication Create a key in the Upscale app (or with POST /user/api keys from an authenticated session) — the raw key is shown once, at creation time. Pass it as a bearer token: A key inherits the permissions of the user it belongs to and stays valid until it is deleted, refreshed or expires. Trading over the API is enabled per account: an account with api trading turned off answers 403 ( api trading not enabled ) to every request made with a key, and account lists leave it out entirely. Conventions Amounts, prices, leverage and multipliers travel as fp9 raw integer strings — the value scaled by 10⁹. \"1000000000\" is 1 USD, \"10000000000\" is 10x leverage, \"50000000\" is 5%. fp9 fixes the scale, not the unit. A quote amount is USD; a base size is units of the traded asset. amount on an order is quote on increase orders and base on close orders — every field says which of the two it carries. Identifiers are uuid v4. Markets are addressed by identifier when trading and by base asset ticker ( BTC ) on the per market read endpoints. Lists page through limit and offset and return the total count next to the page. Positions and orders are scoped to the phase the account is in right now: what belongs to a finished phase is no longer returned. Rate limits Limits are counted per key, in fixed windows, separately for read (GET) and write (everything else) endpoints. Defaults are 10 requests per second and 60 per minute for reads, 10 per second and 60 per minute for writes. Exceeding a limit returns 429 ( api key rate limit exceeded ) with a Retry After header and a body carrying the bucket ( read / write ), the window that tripped, its limit and retryAt . The key's own limits are the only ones a key is subject to. The per endpoint limits the Upscale app runs into are counted per interactive session and are not applied to API key requests, so no endpoint here carries a tighter limit of its own. Errors A failure answers with { statusCode, message, error } , where error is a stable machine readable code. Branch on that code, not on the message text. 400 — the body, query or path failed schema validation ( validation failed ), or a trading precondition was rejected ( insufficient balance , position not available , and the per operation codes below). 401 — the key is missing, malformed, revoked or expired ( session expired ). 403 — the key was used on an endpoint that does not accept keys ( api key not allowed ), the account belongs to someone else ( account access denied ), API trading is off ( api trading not enabled ), the account is no longer trading ( challenge closed ), has not reached a tradable phase ( account phase not allowed ) or is locked by the managed capital limit ( funded limit trading locked ), the order is no longer active ( order not active ), or the market is paused ( market paused ), close only ( market close only ) or outside the category the account may trade ( market category not allowed ). 404 — no such account ( account not found ), order ( order not found ), position ( position not found ) or market ( market not found ). 409 — a request with the same x idempotency key is still being processed ( idempotency key in flight ), the account is not currently loaded by the trading engine ( account not loaded ), or the market price has not been updated recently enough to trade on ( market price stale ). 429 — the rate limit of the key tripped ( api key rate limit exceeded ). Order level rejections come back as 400 with a code naming the field combination at fault; each trading operation lists the ones it can produce. Operations GET /accounts/{accountId}/equity history — Get the equity history of the trader account GET /accounts/{accountId}/risk status — Get the risk status of the trader account GET /accounts/{accountId}/stats — Get trading stats of the trader account POST /accounts/{accountId}/close all — Close all positions and orders GET /accounts/events — Get the events of the trader account GET /accounts/risk status — Get all accounts of current user risk status GET /accounts/with risk status — Get all accounts of current user with risk status GET /v2/markets — Get markets list GET /v2/markets/{id} — Get market by id POST /orders — Create new order POST /orders/{accountId}/close all — Close all orders GET /orders/{accountId}/active — Get all active orders GET /orders/{accountId}/{asset}/active — Get active orders by ticker GET /orders/{accountId}/{asset}/history — Get orders history by ticker PATCH /orders/{orderId} — Change order trigger price DELETE /orders/{orderId} — Cancel order GET /positions/{accountId}/active — Get all active positions GET /positions/{accountId}/portfolio/history — Get all positions history GET /positions/{positionId}/history — Get all events by position GET /positions/{positionId} — Get position details PATCH /positions/{positionId}/margin — Change position margin POST /positions/{accountId}/close all — Close all positions GET /positions/{accountId}/{asset}/history — Get positions history by ticker GET /positions/{accountId}/{asset}/active — Get active positions by ticker GET /positions/{accountId}/{asset}/open notional — Get current open interest by ticker GET /positions/{accountId}/{asset}/chart events — Get position events for chart indicators by ticker GET /positions/{accountId}/{asset}/chart events/buckets — Get position events for chart indicators grouped by candles GET /positions/{accountId}/{asset}/scalping coefficient — Get scalping coefficient for ticker","api":{"title":"Upscale Public API","version":"d796ac9","documentation":"https://docs.upscale.trade/developers","playgroundServer":"https://api.upscale.trade"}}