{"format":"opendoc-document","version":1,"url":"https://docs.upscale.trade/es/developers","title":"API pública de Upscale","description":"Acceso programático al trading de Upscale con una clave de API personal. Solo los endpoints listados aquí aceptan una clave de API — todo lo demás requiere…","kind":"api-overview","locale":"es","inLanguage":"es","translation":{"sourceLanguage":"en","targetLanguage":"es","status":"complete","translatedUnits":80,"totalUnits":80},"lastModified":"2026-09-28T20:05:09.350Z","revision":"3c2fd254d25c5fe88817d5c939afd24407f25862bdfb7b9dc8ab5105728c7abe","section":{"title":"Developers","url":"https://docs.upscale.trade/es/developers"},"representations":{"html":"https://docs.upscale.trade/es/developers","markdown":"https://docs.upscale.trade/es/developers.md","json":"https://docs.upscale.trade/es/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":"Qué es el prop trading","url":"https://docs.upscale.trade/es"},{"title":"API pública de Upscale","url":"https://docs.upscale.trade/es/developers"}],"headings":[{"depth":2,"id":"quick-start","title":"Inicio rápido"},{"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":"A dónde ir a continuación"},{"depth":2,"id":"authentication","title":"Autenticación"},{"depth":2,"id":"conventions","title":"Convenciones"},{"depth":2,"id":"rate-limits","title":"Límites de velocidad"},{"depth":2,"id":"errors","title":"Errores"},{"depth":2,"id":"operations","title":"Operaciones"}],"markdown":"---\ntitle: API pública de Upscale\nicon: book-open\napiVersion: d796ac9\n---\n\nAcceso programático al trading de Upscale con una clave de API personal.\nSolo los endpoints listados aquí aceptan una clave de API — todo lo demás requiere una sesión interactiva.\n\n<a id=\"quick-start\"></a>\n\n## Inicio rápido\n\nAbrir y cerrar una posición requiere cinco llamadas. Todo lo que aparece a continuación se ejecuta contra `https://api.upscale.trade` con una única\nclave de API personal en el encabezado `Authorization` — consulta [Autenticación](/es/developers#authentication) para saber cómo obtener una.\n\n| # | Llamada | Qué te ofrece |\n|---|------|-------------------|\n| 1 | `GET /accounts/with-risk-status` | Las cuentas en las que la clave puede operar, cada una con su fase, estado, saldo y equity. Toma `accountId` de la cuenta en la que se va a operar. |\n| 2 | `GET /v2/markets?accountId=…` | Los mercados negociables con el precio, las comisiones y los límites de apalancamiento contra los que se comprueba una orden en esa cuenta. Toma `id` del mercado. |\n| 3 | `POST /orders` con `type: \"market\"` | Abre la posición. `amount` es la reserva de cotización a gastar, `leverage` el multiplicador. |\n| 4 | `GET /positions/{accountId}/active` | Las posiciones abiertas. Se necesitan porque la respuesta de la orden no lleva ningún identificador de posición. |\n| 5 | `POST /orders` con `type: \"take\"` y `triggerPrice: \"0\"` | Cierra esa posición a mercado. `amount` es el tamaño base a cerrar. |\n\nTres cosas que resolver antes de escribir cualquier código:\n\n- **Cada número es una cadena sin procesar fp9** — el valor escalado por 10⁹. 100 USD es `\"100000000000\"`, el apalancamiento de 10x es\n  `\"10000000000\"`. Léelos y escríbelos con `BigInt` / `Decimal`; un float redondea silenciosamente los últimos dígitos.\n- **`amount` cambia de unidad con la clase de orden.** En la orden `market` que abre una posición, es un importe de **cotización**\n  — margen, comisión, spread y buffer reservados del saldo libre. En la orden `take` que la cierra,\n  es el tamaño del **activo base** de la posición, y no se reserva nada. El paso 5 pasa el `size` de la posición directamente.\n- **Cerrar es una orden `take`, no una orden de mercado en la dirección contraria.** Las posiciones se mantienen por dirección, así que una orden de mercado `short`\n  colocada contra una `long` abierta abre una segunda posición en lugar de cerrar la primera. Una `take` con\n  `triggerPrice: \"0\"` no lleva disparador y se ejecuta a mercado mientras la llamada sigue abierta; un `amount` mayor que\n  la posición mantenida la cierra por completo. Para aplanar una cuenta en una sola llamada, usa `POST /positions/{accountId}/close-all`.\n\nAmbos scripts a continuación están completos: establece `UPSCALE_API_KEY` en el entorno y ejecuta.\n\n<a id=\"javascript-node-18\"></a>\n\n### JavaScript (Node 18+)\n\nGuarda como `upscale.mjs` y ejecuta con `node upscale.mjs` — sin dependencias.\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\nRequiere `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### A dónde ir a continuación\n\n- Las entradas diferidas (`limit`, `stop_market`, `stop_limit`) y las órdenes protectoras (`stop`, `trailing_stop`) toman la misma\n  `POST /orders` ruta — la operación enumera lo que requiere cada tipo.\n- Un stop-loss y un take-profit pueden acompañar a la orden de apertura como `stopTriggerPrice` y `takeTriggerPrice`.\n- `GET /accounts/{accountId}/risk-status` es el endpoint que se debe consultar periódicamente para obtener el margen disponible de drawdown mientras una posición está abierta.\n\n\n<a id=\"authentication\"></a>\n\n## Autenticación\n\nCrea una clave en la aplicación Upscale (o con `POST /user/api-keys` desde una sesión autenticada) — la clave sin procesar\nse muestra una sola vez, en el momento de la creación. Pásala como token de portador:\n\n```\nAuthorization: Bearer usk_<your key>\n```\n\nUna clave hereda los permisos del usuario al que pertenece y permanece válida hasta que se elimina, se renueva o caduca.\n\nEl trading a través de la API se habilita por cuenta: una cuenta con `api_trading` desactivado responde `403`\n(`api_trading_not_enabled`) a cada solicitud realizada con una clave, y las listas de cuentas lo omiten por completo.\n\n<a id=\"conventions\"></a>\n\n## Convenciones\n\n- Los importes, precios, apalancamiento y multiplicadores viajan como **fp9 cadenas de enteros sin procesar** — el valor escalado por 10⁹.\n  `\"1000000000\"` es 1 USD, `\"10000000000\"` es 10x apalancamiento, `\"50000000\"` es 5%.\n- fp9 fija la escala, no la unidad. Un importe de cotización es USD; un tamaño base son unidades del activo negociado. `amount` en una orden es\n  cotización en órdenes de aumento y base en órdenes de cierre — cada campo dice cuál de los dos contiene.\n- Los identificadores son uuid v4. Los mercados se direccionan por identificador al operar y por el ticker del activo base\n  (`BTC`) en los endpoints de lectura por mercado.\n- Las listas se paginan mediante `limit` y `offset` y devuelven el recuento total junto a la página.\n- Las posiciones y las órdenes están acotadas a la fase en la que se encuentra la cuenta en este momento: lo que pertenece a una fase finalizada\n  ya no se devuelve.\n\n<a id=\"rate-limits\"></a>\n\n## Límites de velocidad\n\nLos límites se cuentan por clave, en ventanas fijas, por separado para los endpoints de lectura (GET) y de escritura (todo lo demás).\nLos valores predeterminados son 10 solicitudes por segundo y 60 por minuto\npara lecturas, 10 por segundo y 60 por minuto para escrituras.\n\nSuperar un límite devuelve `429` (`api_key_rate_limit_exceeded`) con un encabezado `Retry-After` y un cuerpo\nque contiene el bucket (`read` / `write`), la ventana que se activó, su límite y `retryAt`.\n\nLos límites propios de la clave son los únicos a los que está sujeta una clave. Los límites por endpoint con los que se topa la aplicación Upscale\nse cuentan por sesión interactiva y no se aplican a las solicitudes con clave de API, por lo que ningún endpoint aquí tiene un\nlímite más estricto propio.\n\n<a id=\"errors\"></a>\n\n## Errores\n\nUn fallo responde con `{ statusCode, message, error }`, donde `error` es un código estable legible por máquina.\nBifurque según ese código, no según el texto del mensaje.\n\n- `400` — el cuerpo, la consulta o la ruta no superaron la validación del esquema (`validation_failed`), o se rechazó una precondición de trading\n  (`insufficient_balance`, `position_not_available`, y los códigos por operación a continuación).\n- `401` — la clave falta, está malformada, revocada o caducada (`session_expired`).\n- `403` — la clave se usó en un endpoint que no acepta claves (`api_key_not_allowed`), la cuenta pertenece\n  a otra persona (`account_access_denied`), el trading por API está desactivado (`api_trading_not_enabled`), la cuenta ya no\n  opera (`challenge_closed`), no ha alcanzado una fase negociable (`account_phase_not_allowed`) o está bloqueada\n  por el límite de capital gestionado (`funded_limit_trading_locked`), la orden ya no está activa\n  (`order_not_active`), o el mercado está pausado (`market_paused`), solo cierre (`market_close_only`) o fuera de\n  la categoría en la que la cuenta puede operar (`market_category_not_allowed`).\n- `404` — no existe tal cuenta (`account_not_found`), orden (`order_not_found`), posición (`position_not_found`)\n  o mercado (`market_not_found`).\n- `409` — una solicitud con la misma `x-idempotency-key` todavía se está procesando (`idempotency_key_in_flight`),\n  la cuenta no está cargada actualmente por el motor de trading (`account_not_loaded`), o el precio de mercado no\n  se ha actualizado lo suficientemente recientemente como para operar con él (`market_price_stale`).\n- `429` — se superó el límite de velocidad de la clave (`api_key_rate_limit_exceeded`).\n\nLos rechazos a nivel de orden se devuelven como `400` con un código que nombra la combinación de campos en conflicto; cada operación de trading\nenumera los que puede producir.\n\n\n<a id=\"operations\"></a>\n\n## Operaciones\n\n- [GET /accounts/{accountId}/equity-history — Obtener el historial de capital de la cuenta del trader](/es/developers/operations/getaccountequityhistory)\n\n- [GET /accounts/{accountId}/risk-status — Obtener el estado de riesgo de la cuenta del trader](/es/developers/operations/getaccountriskstatus)\n\n- [GET /accounts/{accountId}/stats — Obtener estadísticas de trading de la cuenta del trader](/es/developers/operations/getaccounttradingstats)\n\n- [POST /accounts/{accountId}/close-all — Cerrar todas las posiciones y órdenes](/es/developers/operations/closeallpositionsandorders)\n\n- [GET /accounts/events — Obtener los eventos de la cuenta del trader](/es/developers/operations/getaccountsevents)\n\n- [GET /accounts/risk-status — Obtener el estado de riesgo de todas las cuentas del usuario actual.](/es/developers/operations/getaccountsriskstatus)\n\n- [GET /accounts/with-risk-status — Obtener todas las cuentas del usuario actual con estado de riesgo](/es/developers/operations/getaccountswithriskstatus)\n\n- [GET /v2/markets — Obtener lista de mercados](/es/developers/operations/getmarkets)\n\n- [GET /v2/markets/{id} — Obtener mercado por id](/es/developers/operations/getmarket)\n\n- [POST /orders — Crear nueva orden](/es/developers/operations/createorder)\n\n- [POST /orders/{accountId}/close-all — Cerrar todas las órdenes](/es/developers/operations/closeallorders)\n\n- [GET /orders/{accountId}/active — Obtener todas las órdenes activas](/es/developers/operations/getactiveorders)\n\n- [GET /orders/{accountId}/{asset}/active — Obtener órdenes activas por ticker](/es/developers/operations/getactiveordersbyticker)\n\n- [GET /orders/{accountId}/{asset}/history — Obtener el historial de órdenes por ticker](/es/developers/operations/getordershistorybyticker)\n\n- [PATCH /orders/{orderId} — Cambiar el precio de activación de la orden](/es/developers/operations/updateorder)\n\n- [DELETE /orders/{orderId} — Cancelar orden](/es/developers/operations/cancelorder)\n\n- [GET /positions/{accountId}/active — Obtener todas las posiciones activas](/es/developers/operations/getactivepositions)\n\n- [GET /positions/{accountId}/portfolio/history — Obtener el historial de todas las posiciones](/es/developers/operations/getpositionshistory)\n\n- [GET /positions/{positionId}/history — Obtener todos los eventos por posición](/es/developers/operations/getpositionevents)\n\n- [GET /positions/{positionId} — Obtener detalles de la posición](/es/developers/operations/getposition)\n\n- [PATCH /positions/{positionId}/margin — Cambiar el margen de la posición](/es/developers/operations/changemargin)\n\n- [POST /positions/{accountId}/close-all — Cerrar todas las posiciones](/es/developers/operations/closeallpositions)\n\n- [GET /positions/{accountId}/{asset}/history — Obtener el historial de posiciones por ticker](/es/developers/operations/getpositionshistorybyticker)\n\n- [GET /positions/{accountId}/{asset}/active — Obtener las posiciones activas por ticker](/es/developers/operations/getactivepositionsbyticker)\n\n- [GET /positions/{accountId}/{asset}/open-notional — Obtener el interés abierto actual por ticker](/es/developers/operations/getopennotionalbyticker)\n\n- [GET /positions/{accountId}/{asset}/chart-events — Obtener eventos de posición para indicadores de gráfico por ticker](/es/developers/operations/getchartevents)\n\n- [GET /positions/{accountId}/{asset}/chart-events/buckets — Obtener eventos de posición para indicadores del gráfico agrupados por velas](/es/developers/operations/getcharteventbuckets)\n\n- [GET /positions/{accountId}/{asset}/scalping-coefficient — Obtener el coeficiente de scalping para el ticker](/es/developers/operations/getscalpingcoefficient)","text":"Acceso programático al trading de Upscale con una clave de API personal. Solo los endpoints listados aquí aceptan una clave de API — todo lo demás requiere una sesión interactiva. Inicio rápido Abrir y cerrar una posición requiere cinco llamadas. Todo lo que aparece a continuación se ejecuta contra https://api.upscale.trade con una única clave de API personal en el encabezado Authorization — consulta Autenticación para saber cómo obtener una. Llamada Qué te ofrece 1 GET /accounts/with risk status Las cuentas en las que la clave puede operar, cada una con su fase, estado, saldo y equity. Toma accountId de la cuenta en la que se va a operar. 2 GET /v2/markets?accountId=… Los mercados negociables con el precio, las comisiones y los límites de apalancamiento contra los que se comprueba una orden en esa cuenta. Toma id del mercado. 3 POST /orders con type: \"market\" Abre la posición. amount es la reserva de cotización a gastar, leverage el multiplicador. 4 GET /positions/{accountId}/active Las posiciones abiertas. Se necesitan porque la respuesta de la orden no lleva ningún identificador de posición. 5 POST /orders con type: \"take\" y triggerPrice: \"0\" Cierra esa posición a mercado. amount es el tamaño base a cerrar. Tres cosas que resolver antes de escribir cualquier código: Cada número es una cadena sin procesar fp9 — el valor escalado por 10⁹. 100 USD es \"100000000000\" , el apalancamiento de 10x es \"10000000000\" . Léelos y escríbelos con BigInt / Decimal ; un float redondea silenciosamente los últimos dígitos. amount cambia de unidad con la clase de orden. En la orden market que abre una posición, es un importe de cotización — margen, comisión, spread y buffer reservados del saldo libre. En la orden take que la cierra, es el tamaño del activo base de la posición, y no se reserva nada. El paso 5 pasa el size de la posición directamente. Cerrar es una orden take , no una orden de mercado en la dirección contraria. Las posiciones se mantienen por dirección, así que una orden de mercado short colocada contra una long abierta abre una segunda posición en lugar de cerrar la primera. Una take con triggerPrice: \"0\" no lleva disparador y se ejecuta a mercado mientras la llamada sigue abierta; un amount mayor que la posición mantenida la cierra por completo. Para aplanar una cuenta en una sola llamada, usa POST /positions/{accountId}/close all . Ambos scripts a continuación están completos: establece UPSCALE API KEY en el entorno y ejecuta. JavaScript (Node 18+) Guarda como upscale.mjs y ejecuta con node upscale.mjs — sin dependencias. Python (3.10+) Requiere requests ( pip install requests ). A dónde ir a continuación Las entradas diferidas ( limit , stop market , stop limit ) y las órdenes protectoras ( stop , trailing stop ) toman la misma POST /orders ruta — la operación enumera lo que requiere cada tipo. Un stop loss y un take profit pueden acompañar a la orden de apertura como stopTriggerPrice y takeTriggerPrice . GET /accounts/{accountId}/risk status es el endpoint que se debe consultar periódicamente para obtener el margen disponible de drawdown mientras una posición está abierta. Autenticación Crea una clave en la aplicación Upscale (o con POST /user/api keys desde una sesión autenticada) — la clave sin procesar se muestra una sola vez, en el momento de la creación. Pásala como token de portador: Una clave hereda los permisos del usuario al que pertenece y permanece válida hasta que se elimina, se renueva o caduca. El trading a través de la API se habilita por cuenta: una cuenta con api trading desactivado responde 403 ( api trading not enabled ) a cada solicitud realizada con una clave, y las listas de cuentas lo omiten por completo. Convenciones Los importes, precios, apalancamiento y multiplicadores viajan como fp9 cadenas de enteros sin procesar — el valor escalado por 10⁹. \"1000000000\" es 1 USD, \"10000000000\" es 10x apalancamiento, \"50000000\" es 5%. fp9 fija la escala, no la unidad. Un importe de cotización es USD; un tamaño base son unidades del activo negociado. amount en una orden es cotización en órdenes de aumento y base en órdenes de cierre — cada campo dice cuál de los dos contiene. Los identificadores son uuid v4. Los mercados se direccionan por identificador al operar y por el ticker del activo base ( BTC ) en los endpoints de lectura por mercado. Las listas se paginan mediante limit y offset y devuelven el recuento total junto a la página. Las posiciones y las órdenes están acotadas a la fase en la que se encuentra la cuenta en este momento: lo que pertenece a una fase finalizada ya no se devuelve. Límites de velocidad Los límites se cuentan por clave, en ventanas fijas, por separado para los endpoints de lectura (GET) y de escritura (todo lo demás). Los valores predeterminados son 10 solicitudes por segundo y 60 por minuto para lecturas, 10 por segundo y 60 por minuto para escrituras. Superar un límite devuelve 429 ( api key rate limit exceeded ) con un encabezado Retry After y un cuerpo que contiene el bucket ( read / write ), la ventana que se activó, su límite y retryAt . Los límites propios de la clave son los únicos a los que está sujeta una clave. Los límites por endpoint con los que se topa la aplicación Upscale se cuentan por sesión interactiva y no se aplican a las solicitudes con clave de API, por lo que ningún endpoint aquí tiene un límite más estricto propio. Errores Un fallo responde con { statusCode, message, error } , donde error es un código estable legible por máquina. Bifurque según ese código, no según el texto del mensaje. 400 — el cuerpo, la consulta o la ruta no superaron la validación del esquema ( validation failed ), o se rechazó una precondición de trading ( insufficient balance , position not available , y los códigos por operación a continuación). 401 — la clave falta, está malformada, revocada o caducada ( session expired ). 403 — la clave se usó en un endpoint que no acepta claves ( api key not allowed ), la cuenta pertenece a otra persona ( account access denied ), el trading por API está desactivado ( api trading not enabled ), la cuenta ya no opera ( challenge closed ), no ha alcanzado una fase negociable ( account phase not allowed ) o está bloqueada por el límite de capital gestionado ( funded limit trading locked ), la orden ya no está activa ( order not active ), o el mercado está pausado ( market paused ), solo cierre ( market close only ) o fuera de la categoría en la que la cuenta puede operar ( market category not allowed ). 404 — no existe tal cuenta ( account not found ), orden ( order not found ), posición ( position not found ) o mercado ( market not found ). 409 — una solicitud con la misma x idempotency key todavía se está procesando ( idempotency key in flight ), la cuenta no está cargada actualmente por el motor de trading ( account not loaded ), o el precio de mercado no se ha actualizado lo suficientemente recientemente como para operar con él ( market price stale ). 429 — se superó el límite de velocidad de la clave ( api key rate limit exceeded ). Los rechazos a nivel de orden se devuelven como 400 con un código que nombra la combinación de campos en conflicto; cada operación de trading enumera los que puede producir. Operaciones GET /accounts/{accountId}/equity history — Obtener el historial de capital de la cuenta del trader GET /accounts/{accountId}/risk status — Obtener el estado de riesgo de la cuenta del trader GET /accounts/{accountId}/stats — Obtener estadísticas de trading de la cuenta del trader POST /accounts/{accountId}/close all — Cerrar todas las posiciones y órdenes GET /accounts/events — Obtener los eventos de la cuenta del trader GET /accounts/risk status — Obtener el estado de riesgo de todas las cuentas del usuario actual. GET /accounts/with risk status — Obtener todas las cuentas del usuario actual con estado de riesgo GET /v2/markets — Obtener lista de mercados GET /v2/markets/{id} — Obtener mercado por id POST /orders — Crear nueva orden POST /orders/{accountId}/close all — Cerrar todas las órdenes GET /orders/{accountId}/active — Obtener todas las órdenes activas GET /orders/{accountId}/{asset}/active — Obtener órdenes activas por ticker GET /orders/{accountId}/{asset}/history — Obtener el historial de órdenes por ticker PATCH /orders/{orderId} — Cambiar el precio de activación de la orden DELETE /orders/{orderId} — Cancelar orden GET /positions/{accountId}/active — Obtener todas las posiciones activas GET /positions/{accountId}/portfolio/history — Obtener el historial de todas las posiciones GET /positions/{positionId}/history — Obtener todos los eventos por posición GET /positions/{positionId} — Obtener detalles de la posición PATCH /positions/{positionId}/margin — Cambiar el margen de la posición POST /positions/{accountId}/close all — Cerrar todas las posiciones GET /positions/{accountId}/{asset}/history — Obtener el historial de posiciones por ticker GET /positions/{accountId}/{asset}/active — Obtener las posiciones activas por ticker GET /positions/{accountId}/{asset}/open notional — Obtener el interés abierto actual por ticker GET /positions/{accountId}/{asset}/chart events — Obtener eventos de posición para indicadores de gráfico por ticker GET /positions/{accountId}/{asset}/chart events/buckets — Obtener eventos de posición para indicadores del gráfico agrupados por velas GET /positions/{accountId}/{asset}/scalping coefficient — Obtener el coeficiente de scalping para el ticker","api":{"title":"API pública de Upscale","version":"d796ac9","documentation":"https://docs.upscale.trade/es/developers","playgroundServer":"https://api.upscale.trade"}}