{"format":"opendoc-document","version":1,"url":"https://docs.upscale.trade/ru/developers","title":"Публичный API Upscale","description":"Программный доступ к торговле в Upscale с личным API ключом. Только перечисленные здесь эндпоинты принимают API ключ — всё остальное требует интерактивной…","kind":"api-overview","locale":"ru","inLanguage":"ru","translation":{"sourceLanguage":"en","targetLanguage":"ru","status":"complete","translatedUnits":80,"totalUnits":80},"lastModified":"2026-09-28T20:14:21.334Z","revision":"4bcdb0248fec5130d7dca32f21ced4a207c71ff2d711894a920c99e4198fedd7","section":{"title":"Developers","url":"https://docs.upscale.trade/ru/developers"},"representations":{"html":"https://docs.upscale.trade/ru/developers","markdown":"https://docs.upscale.trade/ru/developers.md","json":"https://docs.upscale.trade/ru/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":"Что такое проп-трейдинг","url":"https://docs.upscale.trade/ru"},{"title":"Публичный API Upscale","url":"https://docs.upscale.trade/ru/developers"}],"headings":[{"depth":2,"id":"quick-start","title":"Быстрый старт"},{"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":"Куда двигаться дальше"},{"depth":2,"id":"authentication","title":"Аутентификация"},{"depth":2,"id":"conventions","title":"Соглашения"},{"depth":2,"id":"rate-limits","title":"Лимиты запросов"},{"depth":2,"id":"errors","title":"Ошибки"},{"depth":2,"id":"operations","title":"Операции"}],"markdown":"---\ntitle: Публичный API Upscale\nicon: book-open\napiVersion: d796ac9\n---\n\nПрограммный доступ к торговле в Upscale с личным API-ключом.\nТолько перечисленные здесь эндпоинты принимают API-ключ — всё остальное требует интерактивной сессии.\n\n<a id=\"quick-start\"></a>\n\n## Быстрый старт\n\nОткрытие и закрытие позиции занимает пять вызовов. Всё ниже выполняется на `https://api.upscale.trade` с одним\nличным API-ключом в заголовке `Authorization` — см. [Аутентификация](/ru/developers#authentication), чтобы узнать, как его получить.\n\n| # | Вызов | Что это даёт вам |\n|---|------|-------------------|\n| 1 | `GET /accounts/with-risk-status` | Счета, которыми ключ может торговать, каждый со своей фазой, статусом, балансом и эквити. Возьмите `accountId` у того, на котором будете торговать. |\n| 2 | `GET /v2/markets?accountId=…` | Торгуемые рынки с ценой, комиссиями и границами кредитного плеча, по которым проверяется ордер на этом счёте. Возьмите `id` рынка. |\n| 3 | `POST /orders` с `type: \"market\"` | Открывает позицию. `amount` — это резерв в котируемой валюте, который нужно потратить, `leverage` — множитель. |\n| 4 | `GET /positions/{accountId}/active` | Открытые позиции. Нужно, потому что ответ ордера не содержит идентификатор позиции. |\n| 5 | `POST /orders` с `type: \"take\"` и `triggerPrice: \"0\"` | Закрывает эту позицию по рынку. `amount` — это базовый размер для закрытия. |\n\nТри вещи, которые нужно определить перед написанием любого кода:\n\n- **Каждое число — это необработанная строка fp9** — значение, умноженное на 10⁹. 100 USD — это `\"100000000000\"`, 10x плечо — это\n  `\"10000000000\"`. Читайте и записывайте их с помощью `BigInt` / `Decimal`; число с плавающей запятой незаметно отбрасывает последние цифры.\n- **`amount` меняет единицу измерения в зависимости от класса ордера.** Для ордера `market`, который открывает позицию, это **quote**-сумма — маржа, комиссия, спред и буфер, зарезервированные из свободного баланса. Для ордера `take`, который её закрывает, это размер позиции в **базовом активе**, и ничего не резервируется. Шаг 5 передаёт `size` позиции напрямую.\n- **Закрытие — это ордер `take`, а не рыночный ордер в обратную сторону.** Позиции ведутся по направлению, поэтому рыночный ордер `short`, размещённый против открытой `long`, открывает вторую позицию вместо закрытия первой. Ордер `take` с   `triggerPrice: \"0\"` не имеет триггера и исполняется по рынку, пока вызов ещё открыт; `amount`, превышающий удерживаемую позицию, закрывает её полностью. Чтобы закрыть все позиции на счёте одним вызовом, используйте `POST /positions/{accountId}/close-all`.\n\nОба скрипта ниже полны: задайте `UPSCALE_API_KEY` в окружении и запустите.\n\n<a id=\"javascript-node-18\"></a>\n\n### JavaScript (Node 18+)\n\nСохраните как `upscale.mjs` и запустите с помощью `node upscale.mjs` — без зависимостей.\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<a id=\"python-3-10\"></a>\n\n### Python (3.10+)\n\nТребуется `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<a id=\"where-to-go-next\"></a>\n\n### Куда двигаться дальше\n\n- Отложенные входы (`limit`, `stop_market`, `stop_limit`) и защитные ордера (`stop`, `trailing_stop`) используют один и тот же\n  `POST /orders` маршрут — операция перечисляет, что требуется для каждого типа.\n- Стоп-лосс и тейк-профит могут идти вместе с ордером на открытие как `stopTriggerPrice` и `takeTriggerPrice`.\n- `GET /accounts/{accountId}/risk-status` — это эндпоинт, который нужно опрашивать для проверки запаса по просадке, пока позиция открыта.\n\n\n<a id=\"authentication\"></a>\n\n## Аутентификация\n\nСоздайте ключ в приложении Upscale (или с помощью `POST /user/api-keys` из аутентифицированной сессии) — необработанный ключ\nпоказывается один раз, в момент создания. Передавайте его как bearer-токен:\n\n```\nAuthorization: Bearer usk_<your key>\n```\n\nКлюч наследует разрешения пользователя, которому он принадлежит, и остаётся действительным, пока он не будет удалён, обновлён или не истечёт.\n\nТорговля через API включается отдельно для каждого аккаунта: аккаунт с выключенным `api_trading` отвечает `403`\n(`api_trading_not_enabled`) на каждый запрос, сделанный с ключом, а списки аккаунтов полностью его исключают.\n\n<a id=\"conventions\"></a>\n\n## Соглашения\n\n- Суммы, цены, кредитное плечо и множители передаются как **fp9 необработанные целочисленные строки** — значение, масштабированное на 10⁹.\n  `\"1000000000\"` — это 1 USD, `\"10000000000\"` — это 10x кредитное плечо, `\"50000000\"` — это 5%.\n- fp9 фиксирует масштаб, а не единицу измерения. Сумма в котируемой валюте — это USD; размер базового актива — это единицы торгуемого актива. `amount` в ордере — это\n  котируемая сумма в ордерах на увеличение и базовый размер в ордерах на закрытие — каждое поле указывает, какое из двух значений оно содержит.\n- Идентификаторы — это uuid v4. К рынкам обращаются по идентификатору при торговле и по тикеру базового актива\n  (`BTC`) на эндпоинтах чтения по каждому рынку.\n- Списки разбиваются на страницы с помощью `limit` и `offset` и возвращают общее количество рядом со страницей.\n- Позиции и ордера привязаны к фазе, в которой аккаунт находится прямо сейчас: то, что относится к завершённой\n  фазе, больше не возвращается.\n\n<a id=\"rate-limits\"></a>\n\n## Лимиты запросов\n\nЛимиты считаются по ключу, в фиксированных окнах, отдельно для эндпоинтов чтения (GET) и записи (всё остальное).\nПо умолчанию: 10 запросов в секунду и 60 в минуту\nдля чтения, 10 в секунду и 60 в минуту для записи.\n\nПревышение лимита возвращает `429` (`api_key_rate_limit_exceeded`) с заголовком `Retry-After` и телом\nсодержащим бакет (`read` / `write`), окно, которое сработало, его лимит и `retryAt`.\n\nКлюч подчиняется только своим собственным лимитам. Лимиты для отдельных эндпоинтов, с которыми сталкивается приложение Upscale,\nсчитаются по каждой интерактивной сессии и не применяются к запросам с API-ключом, поэтому ни один эндпоинт здесь не имеет\nболее строгого собственного лимита.\n\n<a id=\"errors\"></a>\n\n## Ошибки\n\nПри сбое возвращается `{ statusCode, message, error }`, где `error` — стабильный машиночитаемый код.\nВетвление выполняйте по этому коду, а не по тексту сообщения.\n\n- `400` — тело, query или path не прошли проверку схемы (`validation_failed`), или торговое предусловие\n  было отклонено (`insufficient_balance`, `position_not_available` и коды для отдельных операций ниже).\n- `401` — ключ отсутствует, имеет неверный формат, отозван или истёк (`session_expired`).\n- `403` — ключ был использован на эндпоинте, который не принимает ключи (`api_key_not_allowed`), счёт принадлежит\n  кому-то другому (`account_access_denied`), API-торговля отключена (`api_trading_not_enabled`), счёт больше не\n  торгует (`challenge_closed`), не достиг фазы, допускающей торговлю (`account_phase_not_allowed`), или заблокирован\n  лимитом управляемого капитала (`funded_limit_trading_locked`), ордер больше не активен\n  (`order_not_active`), или рынок приостановлен (`market_paused`), работает только на закрытие (`market_close_only`) или находится вне\n  категории, в которой счёт может торговать (`market_category_not_allowed`).\n- `404` — нет такого аккаунта (`account_not_found`), ордера (`order_not_found`), позиции (`position_not_found`)\n  или рынка (`market_not_found`).\n- `409` — запрос с тем же `x-idempotency-key` всё ещё обрабатывается (`idempotency_key_in_flight`),\n  аккаунт в данный момент не загружен торговым движком (`account_not_loaded`), или рыночная цена не\n  обновлялась достаточно недавно, чтобы торговать по ней (`market_price_stale`).\n- `429` — сработал лимит частоты запросов для ключа (`api_key_rate_limit_exceeded`).\n\nОтклонения на уровне ордера возвращаются как `400` с кодом, указывающим проблемную комбинацию полей; каждая торговая\nоперация перечисляет те, которые она может выдать.\n\n\n<a id=\"operations\"></a>\n\n## Операции\n\n- [GET /accounts/{accountId}/equity-history — Получить историю эквити счета трейдера](/ru/developers/operations/getaccountequityhistory)\n\n- [GET /accounts/{accountId}/risk-status — Получить статус риска торгового аккаунта](/ru/developers/operations/getaccountriskstatus)\n\n- [GET /accounts/{accountId}/stats — Получить торговую статистику аккаунта трейдера](/ru/developers/operations/getaccounttradingstats)\n\n- [POST /accounts/{accountId}/close-all — Закрыть все позиции и ордера](/ru/developers/operations/closeallpositionsandorders)\n\n- [GET /accounts/events — Получить события торгового аккаунта](/ru/developers/operations/getaccountsevents)\n\n- [GET /accounts/risk-status — Получить статус риска всех аккаунтов текущего пользователя](/ru/developers/operations/getaccountsriskstatus)\n\n- [GET /accounts/with-risk-status — Получить все счета текущего пользователя со статусом риска](/ru/developers/operations/getaccountswithriskstatus)\n\n- [GET /v2/markets — Получить список рынков](/ru/developers/operations/getmarkets)\n\n- [GET /v2/markets/{id} — Получить рынок по id](/ru/developers/operations/getmarket)\n\n- [POST /orders — Создать новый ордер](/ru/developers/operations/createorder)\n\n- [POST /orders/{accountId}/close-all — Закрыть все ордера](/ru/developers/operations/closeallorders)\n\n- [GET /orders/{accountId}/active — Получить все активные ордера](/ru/developers/operations/getactiveorders)\n\n- [GET /orders/{accountId}/{asset}/active — Получить активные ордера по тикеру](/ru/developers/operations/getactiveordersbyticker)\n\n- [GET /orders/{accountId}/{asset}/history — Получить историю ордеров по тикеру](/ru/developers/operations/getordershistorybyticker)\n\n- [PATCH /orders/{orderId} — Изменить триггерную цену ордера](/ru/developers/operations/updateorder)\n\n- [DELETE /orders/{orderId} — Отменить ордер](/ru/developers/operations/cancelorder)\n\n- [GET /positions/{accountId}/active — Получить все активные позиции](/ru/developers/operations/getactivepositions)\n\n- [GET /positions/{accountId}/portfolio/history — Получить всю историю позиций](/ru/developers/operations/getpositionshistory)\n\n- [GET /positions/{positionId}/history — Получить все события по позиции](/ru/developers/operations/getpositionevents)\n\n- [GET /positions/{positionId} — Получить сведения о позиции](/ru/developers/operations/getposition)\n\n- [PATCH /positions/{positionId}/margin — Изменить маржу позиции](/ru/developers/operations/changemargin)\n\n- [POST /positions/{accountId}/close-all — Закрыть все позиции](/ru/developers/operations/closeallpositions)\n\n- [GET /positions/{accountId}/{asset}/history — Получить историю позиций по тикеру](/ru/developers/operations/getpositionshistorybyticker)\n\n- [GET /positions/{accountId}/{asset}/active — Получить активные позиции по тикеру](/ru/developers/operations/getactivepositionsbyticker)\n\n- [GET /positions/{accountId}/{asset}/open-notional — Получить текущий открытый интерес по тикеру](/ru/developers/operations/getopennotionalbyticker)\n\n- [GET /positions/{accountId}/{asset}/chart-events — Получить события позиции для индикаторов графика по тикеру](/ru/developers/operations/getchartevents)\n\n- [GET /positions/{accountId}/{asset}/chart-events/buckets — Получить события позиции для индикаторов графика, сгруппированные по свечам](/ru/developers/operations/getcharteventbuckets)\n\n- [GET /positions/{accountId}/{asset}/scalping-coefficient — Получить коэффициент скальпинга для тикера](/ru/developers/operations/getscalpingcoefficient)","text":"Программный доступ к торговле в Upscale с личным API ключом. Только перечисленные здесь эндпоинты принимают API ключ — всё остальное требует интерактивной сессии. Быстрый старт Открытие и закрытие позиции занимает пять вызовов. Всё ниже выполняется на https://api.upscale.trade с одним личным API ключом в заголовке Authorization — см. Аутентификация, чтобы узнать, как его получить. Вызов Что это даёт вам 1 GET /accounts/with risk status Счета, которыми ключ может торговать, каждый со своей фазой, статусом, балансом и эквити. Возьмите accountId у того, на котором будете торговать. 2 GET /v2/markets?accountId=… Торгуемые рынки с ценой, комиссиями и границами кредитного плеча, по которым проверяется ордер на этом счёте. Возьмите id рынка. 3 POST /orders с type: \"market\" Открывает позицию. amount — это резерв в котируемой валюте, который нужно потратить, leverage — множитель. 4 GET /positions/{accountId}/active Открытые позиции. Нужно, потому что ответ ордера не содержит идентификатор позиции. 5 POST /orders с type: \"take\" и triggerPrice: \"0\" Закрывает эту позицию по рынку. amount — это базовый размер для закрытия. Три вещи, которые нужно определить перед написанием любого кода: Каждое число — это необработанная строка fp9 — значение, умноженное на 10⁹. 100 USD — это \"100000000000\" , 10x плечо — это \"10000000000\" . Читайте и записывайте их с помощью BigInt / Decimal ; число с плавающей запятой незаметно отбрасывает последние цифры. amount меняет единицу измерения в зависимости от класса ордера. Для ордера market , который открывает позицию, это quote сумма — маржа, комиссия, спред и буфер, зарезервированные из свободного баланса. Для ордера take , который её закрывает, это размер позиции в базовом активе , и ничего не резервируется. Шаг 5 передаёт size позиции напрямую. Закрытие — это ордер take , а не рыночный ордер в обратную сторону. Позиции ведутся по направлению, поэтому рыночный ордер short , размещённый против открытой long , открывает вторую позицию вместо закрытия первой. Ордер take с triggerPrice: \"0\" не имеет триггера и исполняется по рынку, пока вызов ещё открыт; amount , превышающий удерживаемую позицию, закрывает её полностью. Чтобы закрыть все позиции на счёте одним вызовом, используйте POST /positions/{accountId}/close all . Оба скрипта ниже полны: задайте UPSCALE API KEY в окружении и запустите. JavaScript (Node 18+) Сохраните как upscale.mjs и запустите с помощью node upscale.mjs — без зависимостей. Python (3.10+) Требуется requests ( pip install requests ). Куда двигаться дальше Отложенные входы ( limit , stop market , stop limit ) и защитные ордера ( stop , trailing stop ) используют один и тот же POST /orders маршрут — операция перечисляет, что требуется для каждого типа. Стоп лосс и тейк профит могут идти вместе с ордером на открытие как stopTriggerPrice и takeTriggerPrice . GET /accounts/{accountId}/risk status — это эндпоинт, который нужно опрашивать для проверки запаса по просадке, пока позиция открыта. Аутентификация Создайте ключ в приложении Upscale (или с помощью POST /user/api keys из аутентифицированной сессии) — необработанный ключ показывается один раз, в момент создания. Передавайте его как bearer токен: Ключ наследует разрешения пользователя, которому он принадлежит, и остаётся действительным, пока он не будет удалён, обновлён или не истечёт. Торговля через API включается отдельно для каждого аккаунта: аккаунт с выключенным api trading отвечает 403 ( api trading not enabled ) на каждый запрос, сделанный с ключом, а списки аккаунтов полностью его исключают. Соглашения Суммы, цены, кредитное плечо и множители передаются как fp9 необработанные целочисленные строки — значение, масштабированное на 10⁹. \"1000000000\" — это 1 USD, \"10000000000\" — это 10x кредитное плечо, \"50000000\" — это 5%. fp9 фиксирует масштаб, а не единицу измерения. Сумма в котируемой валюте — это USD; размер базового актива — это единицы торгуемого актива. amount в ордере — это котируемая сумма в ордерах на увеличение и базовый размер в ордерах на закрытие — каждое поле указывает, какое из двух значений оно содержит. Идентификаторы — это uuid v4. К рынкам обращаются по идентификатору при торговле и по тикеру базового актива ( BTC ) на эндпоинтах чтения по каждому рынку. Списки разбиваются на страницы с помощью limit и offset и возвращают общее количество рядом со страницей. Позиции и ордера привязаны к фазе, в которой аккаунт находится прямо сейчас: то, что относится к завершённой фазе, больше не возвращается. Лимиты запросов Лимиты считаются по ключу, в фиксированных окнах, отдельно для эндпоинтов чтения (GET) и записи (всё остальное). По умолчанию: 10 запросов в секунду и 60 в минуту для чтения, 10 в секунду и 60 в минуту для записи. Превышение лимита возвращает 429 ( api key rate limit exceeded ) с заголовком Retry After и телом содержащим бакет ( read / write ), окно, которое сработало, его лимит и retryAt . Ключ подчиняется только своим собственным лимитам. Лимиты для отдельных эндпоинтов, с которыми сталкивается приложение Upscale, считаются по каждой интерактивной сессии и не применяются к запросам с API ключом, поэтому ни один эндпоинт здесь не имеет более строгого собственного лимита. Ошибки При сбое возвращается { statusCode, message, error } , где error — стабильный машиночитаемый код. Ветвление выполняйте по этому коду, а не по тексту сообщения. 400 — тело, query или path не прошли проверку схемы ( validation failed ), или торговое предусловие было отклонено ( insufficient balance , position not available и коды для отдельных операций ниже). 401 — ключ отсутствует, имеет неверный формат, отозван или истёк ( session expired ). 403 — ключ был использован на эндпоинте, который не принимает ключи ( api key not allowed ), счёт принадлежит кому то другому ( account access denied ), API торговля отключена ( api trading not enabled ), счёт больше не торгует ( challenge closed ), не достиг фазы, допускающей торговлю ( account phase not allowed ), или заблокирован лимитом управляемого капитала ( funded limit trading locked ), ордер больше не активен ( order not active ), или рынок приостановлен ( market paused ), работает только на закрытие ( market close only ) или находится вне категории, в которой счёт может торговать ( market category not allowed ). 404 — нет такого аккаунта ( account not found ), ордера ( order not found ), позиции ( position not found ) или рынка ( market not found ). 409 — запрос с тем же x idempotency key всё ещё обрабатывается ( idempotency key in flight ), аккаунт в данный момент не загружен торговым движком ( account not loaded ), или рыночная цена не обновлялась достаточно недавно, чтобы торговать по ней ( market price stale ). 429 — сработал лимит частоты запросов для ключа ( api key rate limit exceeded ). Отклонения на уровне ордера возвращаются как 400 с кодом, указывающим проблемную комбинацию полей; каждая торговая операция перечисляет те, которые она может выдать. Операции GET /accounts/{accountId}/equity history — Получить историю эквити счета трейдера GET /accounts/{accountId}/risk status — Получить статус риска торгового аккаунта GET /accounts/{accountId}/stats — Получить торговую статистику аккаунта трейдера POST /accounts/{accountId}/close all — Закрыть все позиции и ордера GET /accounts/events — Получить события торгового аккаунта GET /accounts/risk status — Получить статус риска всех аккаунтов текущего пользователя GET /accounts/with risk status — Получить все счета текущего пользователя со статусом риска GET /v2/markets — Получить список рынков GET /v2/markets/{id} — Получить рынок по id POST /orders — Создать новый ордер POST /orders/{accountId}/close all — Закрыть все ордера GET /orders/{accountId}/active — Получить все активные ордера GET /orders/{accountId}/{asset}/active — Получить активные ордера по тикеру GET /orders/{accountId}/{asset}/history — Получить историю ордеров по тикеру PATCH /orders/{orderId} — Изменить триггерную цену ордера DELETE /orders/{orderId} — Отменить ордер GET /positions/{accountId}/active — Получить все активные позиции GET /positions/{accountId}/portfolio/history — Получить всю историю позиций GET /positions/{positionId}/history — Получить все события по позиции GET /positions/{positionId} — Получить сведения о позиции PATCH /positions/{positionId}/margin — Изменить маржу позиции POST /positions/{accountId}/close all — Закрыть все позиции GET /positions/{accountId}/{asset}/history — Получить историю позиций по тикеру GET /positions/{accountId}/{asset}/active — Получить активные позиции по тикеру GET /positions/{accountId}/{asset}/open notional — Получить текущий открытый интерес по тикеру GET /positions/{accountId}/{asset}/chart events — Получить события позиции для индикаторов графика по тикеру GET /positions/{accountId}/{asset}/chart events/buckets — Получить события позиции для индикаторов графика, сгруппированные по свечам GET /positions/{accountId}/{asset}/scalping coefficient — Получить коэффициент скальпинга для тикера","api":{"title":"Публичный API Upscale","version":"d796ac9","documentation":"https://docs.upscale.trade/ru/developers","playgroundServer":"https://api.upscale.trade"}}