You're on the production developer portal. The interactive demo — signup, Sumsub KYC, the purchase flow, webhooks, and the trading dashboard — is disabled here because it would create real accounts. Test those flows in the sandbox against the staging API.

Flows

Trading

Submit orders, manage positions, and read the live trading desk for a funded prop account. Orders are routed to the validator network and reflected back in positions/history.

Always send X-Prop-Account

Trading endpoints act on a specific funded account. Pass its id in the X-Prop-Account header. Get ids from prop accounts.

trade_pair uses the wire id

Use the validator's wire id (e.g. BTCUSD), not a display label like BTC/USD. Sending the wrong format returns 400 Bad Request.

Bots: authenticate with an API key instead

Every endpoint on this page also accepts X-Api-Key: <key_id>.<key_secret> on its own — no bearer or session token needed. Mint one per trader at /docs/api-keys.

Submit an order

POST/v2/trading/orders
User session
Request body
trade_pairstring
required
Wire id, e.g. "BTCUSD"
order_type"LONG" | "SHORT" | "FLAT"
required
Direction
leveragenumberoptionalSize by leverage…
valuenumberoptional…or by notional value…
quantitynumberoptional…or by quantity (pick one)
execution_typestringoptionalMARKET (default), LIMIT, STOP_LIMIT, BRACKET…
limit_pricenumberoptionalFor LIMIT / STOP_LIMIT
stop_pricenumberoptionalFor STOP_LIMIT
take_profitnumberoptionalOptional TP price
stop_lossnumberoptionalOptional SL price
curl
curl -X POST http://localhost:8000/v2/trading/orders \
  -H "Authorization: Bearer <app_access_token>" \
  -H "X-Session-Token: <user_session_token>" \
  -H "X-Prop-Account: prop_..." \
  -H "Content-Type: application/json" \
  -d '{
    "trade_pair": "BTCUSD",
    "order_type": "LONG",
    "leverage": 1.0,
    "execution_type": "MARKET"
  }'
lib/hsc/client.ts
import { trading } from "@/lib/hsc/client";

await trading.submit(
  { trade_pair: "BTCUSD", order_type: "LONG", leverage: 1.0, execution_type: "MARKET" },
  propAccountId,
);
200 OK
{ "success": true, "order_uuid": "ord_...", "message": null, "processing_time": 0.42 }

Manage positions & orders

Endpoints
POST /v2/trading/orders/closebody { trade_pair }optionalFlatten a position
POST /v2/trading/orders/bulk-closebody { position_uuids }optionalClose many at once
DELETE /v2/trading/orders/{uuid}?trade_pair=…optionalCancel a resting order
POST /v2/trading/orders/{uuid}/editbody { trade_pair, order_type, … }optionalEdit a resting order
POST /v2/trading/orders/tp-slbody { trade_pair, take_profit?, stop_loss? }optionalAttach TP/SL

Read the desk

Reads accept X-Prop-Account and return snapshots. desk-poll bundles everything in one round-trip — ideal for a UI refresh loop.

GET/v2/trading/desk-poll
User session
200 OK
{
  "positions": [ /* open positions */ ],
  "orders": [ /* resting orders */ ],
  "history": [ /* closed positions */ ],
  "balance": { "account_size": 25000, "status": "evaluation", "subaccount_info": { /* validator snapshot */ } }
}
GET
/v2/trading/desk-poll Try it in the sandbox

balance.status mirrors the prop-account status — provisioning, subaccount_failed, evaluation, funded or eliminated. It is never active. Both status and subaccount_info are omitted entirely when the account has no synthetic_hotkey yet or the validator fetch fails, so the bundle degrades to { "account_size": 25000 } with empty positions, orders and history.

Individual reads: GET /v2/trading/positions, GET /v2/trading/orders, GET /v2/trading/history, GET /v2/trading/balance.