Advanced REST & WebSocket
Advanced: Direct REST & WebSocket API
Advanced: Direct REST & WebSocket API
For custom code and low-level integrations that call RapidX directly, without the CLI or MCP layer.
Most participants should use the CLI or MCP — see 01-quickstart.md. This document is for cases where you need direct HTTP or WebSocket access: performance-critical bots, languages without Node.js, or custom tooling.
Official API docs: get-account-list
Authentication
Required Headers (REST)
| Header | Value |
|---|---|
X-MBX-APIKEY | Your Access Key |
nonce | Current Unix timestamp in seconds (string) |
signature | HMAC-SHA256 signature (see below) |
Content-Type | application/json |
REST Signature Algorithm
1. Sort request parameters alphabetically by key:
sorted_payload = "key1=val1&key2=val2&..."
2. Append "&" + timestamp:
payload = sorted_payload + "&" + timestamp
(no parameters: payload = "&" + timestamp)
3. HMAC-SHA256 with your Secret Key, hex-encoded:
signature = HMAC-SHA256(secret_key, payload).hexdigest()
Python example:
import hmac, hashlib, time
def sign(params: dict, secret_key: str):
timestamp = str(int(time.time()))
sorted_payload = "&".join(f"{k}={v}" for k, v in sorted(params.items()))
payload = (sorted_payload + "&" if sorted_payload else "&") + timestamp
sig = hmac.new(secret_key.encode(), payload.encode(), hashlib.sha256).hexdigest()
return sig, timestamp
WebSocket Authentication Signature
Different from REST — used for the private WebSocket login:
message = timestamp + "GET" + "/users/self/verify"
sign = HMAC-SHA256(secret_key, message).hexdigest()
REST API Endpoints
Base URL: https://api.ltp-contest.com
For leaderboard/ranking data, see Track A Leaderboard API (
GET /api/v1/tracka/ranking/self) and Track B Ranking — Self Query (GET /api/v1/trackb/ranking/self).
Account & Assets
| Method | Path | Description | Docs |
|---|---|---|---|
| GET | /api/v1/trading/account | Account overview per exchange | → |
| GET | /api/v1/trading/portfolio/assets | Portfolio asset breakdown | → |
| GET | /api/v1/trading/user/tradingStats | Trading statistics (begin, end params) | → |
| GET | /api/v1/trading/userFeeRate | Maker/Taker fee rates + level tier (portfolio key) | → |
| GET | /api/v1/broker/feeRate | Broker fee-rate tiers (Main Portfolio Key + READ) | — |
Orders
| Method | Path | Description | Docs |
|---|---|---|---|
| POST | /api/v1/trading/order | Place order | → |
| PUT | /api/v1/trading/order | Amend order | → |
| DELETE | /api/v1/trading/order | Cancel order | → |
| DELETE | /api/v1/trading/cancelAll | Cancel all orders (sym or exchangeType) | → |
| GET | /api/v1/trading/order | Get single order (orderId or clientOrderId) | → |
| GET | /api/v1/trading/orders | List open orders | → |
| GET | /api/v1/trading/history/orders | Order history (sym optional) | → |
| GET | /api/v1/trading/archive/history/orders | Archived order history | → |
| GET | /api/v1/trading/executions | Execution records | → |
| GET | /api/v1/trading/executions/pageable | Pageable executions | → |
| GET | /api/v1/trading/statement | Trading statement | → |
Place order fields:
| Field | Required | Description |
|---|---|---|
sym | Yes | e.g. BINANCE_PERP_BTC_USDT |
side | Yes | BUY / SELL |
positionSide | Yes (hedge mode) | LONG / SHORT |
orderType | Yes | LIMIT / MARKET |
orderQty | Yes | Base/contract quantity |
limitPrice | For LIMIT | Limit price |
timeInForce | No | GTC (default) / IOC / FOK / GTX |
clientOrderId | Recommended | Max 40 chars |
Order states: NEW → OPEN → PARTIALLY_FILLED → FILLED / CANCELLED / REJECTED
For algo orders (TP/SL, TWAP, VWAP — conditional trigger orders), see Algo Orders.
Positions
| Method | Path | Description | Docs |
|---|---|---|---|
| GET | /api/v1/trading/position | Open positions (sym, exchange optional) | → |
| GET | /api/v1/trading/history/position | Position history | → |
| DELETE | /api/v1/trading/position | Close position (sym, positionSide) | → |
| DELETE | /api/v1/trading/positions | Close all positions (exchangeType, closeAllPos:"true") | → |
| GET | /api/v1/trading/perp/leverage | Get leverage (sym or exchange optional) | → |
| POST | /api/v1/trading/position/leverage | Set leverage (sym, leverage) | → |
| GET | /api/v1/adl/rank | ADL rank (sym optional) | → |
Market Data (RapidX)
| Method | Path | Description | Docs |
|---|---|---|---|
| GET | /api/v1/trading/sym/info | Symbol rules (sym optional) | → |
| GET | /api/v1/market/fundingRate | Funding rate (sym required) | → |
| GET | /api/v1/market/markPrice | Mark price (sym optional) | → |
| GET | /api/v1/trading/positionBracket | Position tier/bracket | → |
| GET | /api/v1/trading/loan/info | Loan info | → |
| GET | /api/v1/trading/coin/discount | Coin discount rate | → |
| GET | /api/v1/trading/margin/leverage | Margin leverage | → |
Rate Limits
| Endpoint | Competition limit |
|---|---|
POST /api/v1/trading/order (place order) | 1 req / 5 s |
PUT /api/v1/trading/order (replace order) | 1 req / 5 s |
DELETE /api/v1/trading/order (cancel order) | 1 req / 5 s |
GET /api/v1/market/fundingRate | 3 req / 10 s |
GET /api/v1/market/markPrice | 3 req / 10 s |
GET /api/v1/trading/sym/info | 3 req / 10 s |
DELETE /api/v1/trading/positions (close all positions) | 1 req / 10 s |
| All other REST endpoints | production rate × 1/5 (see individual endpoint pages) |
For full rate limits and endpoint details, see the official API documentation: https://apidocliquidity.readme.io/reference/place-order
REST Response Format
{
"code": 200000,
"message": "Success",
"data": { ... }
}
code: 200000 = success. Any other value is an error. Error codes →
WebSocket
Connection Hosts
| Service | URL |
|---|---|
| Trading REST API | https://api.ltp-contest.com |
| News Feed REST API | https://api.ltp-contest.com |
| Market Data WebSocket | wss://mds.ltp-contest.com/marketdata/v2/public |
| User Data WebSocket | wss://wss.ltp-contest.com/v1/private |
| News Feed WebSocket | wss://feeds.ltp-contest.com/feeds/v2/public |
The competition hosts resolve to the official production API.
Market Data WebSocket
- URL:
wss://mds.ltp-contest.com/marketdata/v2/public - Supported exchanges:
BINANCE/OKX - Compression: GZIP is enabled by default. Append
?binary=falseto the URL to receive plain-text JSON frames. In Python, decompress GZIP frames withzlib.decompress(data, zlib.MAX_WBITS | 16).
Authentication (optional)
Unauthenticated connections are subject to lower rate limits. To authenticate, send a login message after connecting:
{
"action": "login",
"args": { "apiKey": "YOUR_ACCESS_KEY", "timestamp": "1778140847", "sign": "..." }
}
Field naming differs by message type: login uses
action/args(object); subscribe / unsubscribe useevent/arg(array). Timestamp: the Market Data WS accepts both 10-digit (seconds) and 13-digit (milliseconds) timestamps. The private (User Data) WS only accepts seconds.
Signature:
message = timestamp + "GET" + "/users/self/verify"
sign = HMAC-SHA256(secret_key, message).hexdigest()
Success response:
{ "event": "login", "code": "200000", "msg": "success" }
Rate Limits
| Unauthenticated | Authenticated | |
|---|---|---|
| Max connections per IP | 5 | 40 |
| Max trading pairs per connection | 5 | 50 |
- Subscribe rate: max 50 subscribe/unsubscribe requests per IP per second; exceeding returns error
11260. - Limits are counted by trading pair, not by channel — subscribing BBO + TICKER + TRADE for the same symbol counts as 1 pair.
Heartbeat
The server disconnects after 60 seconds of inactivity. Send {"ping": <timestamp_ms>} every ~20 seconds; the server replies {"pong": <timestamp_ms>}.
Symbol Format
{EXCHANGE}_{TYPE}_{BASE}_{QUOTE} — EXCHANGE: BINANCE / OKX; TYPE: SPOT / PERP. Example: BINANCE_PERP_BTC_USDT.
Subscribe / Unsubscribe
Channel names are case-sensitive and must be uppercase.
{
"event": "subscribe",
"arg": [
{ "channel": "BBO", "sym": "BINANCE_PERP_BTC_USDT" },
{ "channel": "TRADE", "sym": "OKX_PERP_BTC_USDT" }
]
}
Available Channels
| Channel | Frequency | Scope | Docs |
|---|---|---|---|
TICKER | 2000 ms | All | → |
ORDER_BOOK | 250 ms | All | → |
BBO | On change | All | → |
TRADE | Real-time | All | → |
MARK_PRICE | Real-time | Perpetual only | → |
INDEX_PRICE | Real-time | Perpetual only | → |
KLINE | Real-time | All | → |
INDEX_KLINE | Real-time | Perpetual only | → |
MARK_PRICE_KLINE | Real-time | Perpetual only | → |
OPEN_INTEREST | On change | Perpetual only | → |
Error Codes
| Code | Meaning |
|---|---|
200000 | Success |
11100 | Invalid symbol (e.g. SPOT on a perpetual-only channel) |
11101 | Invalid channel |
11102 | Invalid parameter |
11103 | Invalid request |
11106 | Invalid access key |
11107 | Invalid sign / signature |
11108 | Invalid timestamp |
11109 | Permission denied |
11112 | Not subscribed |
11200 | Too many connections per IP |
11210 | Unauthenticated symbol limit (5) exceeded |
11220 | Authenticated symbol limit (50) exceeded |
11230 | Connection not authenticated |
11240 | Subscribe rate limit exceeded |
11250 | Symbol not currently supported |
11260 | Request rate limit exceeded |
User Data WebSocket
- URL:
wss://wss.ltp-contest.com/v1/private - Supported exchanges:
BINANCE/OKX - Authentication required. After login the server auto-pushes orders, trades, assets, positions, and margin-call updates; the same connection can place, replace, and cancel orders.
Login
{
"action": "login",
"args": { "apiKey": "YOUR_ACCESS_KEY", "timestamp": "1778140847", "sign": "..." }
}
- Timestamp: only 10-digit seconds are accepted; a 13-digit millisecond timestamp returns
601016. - Success:
{"event":"login","code":0,"msg":""} - Failure:
{"event":"login","code":601009,"msg":"Login failed"} args.onlyTrade(optional, bool): whentrue, the connection is restricted to order operations only and no data streams are pushed.
Signature:
message = timestamp + "GET" + "/users/self/verify"
sign = HMAC-SHA256(secret_key, message).hexdigest()
Order Actions
{ "id": "p1", "action": "place_order", "args": { ... } }
{ "id": "a1", "action": "replace_order", "args": { "orderId": "...", "replacePrice": "64000" } }
{ "id": "c1", "action": "cancel_order", "args": { "orderId": "..." } }
Orders push channel — auto-subscribed after login. User data streams →
{
"channel": "Orders",
"data": {
"orderId": "1234567890123456",
"clientOrderId": "agent-001",
"orderState": "FILLED",
"executedQty": "0.001",
"executedAvgPrice": "65000"
}
}
Rate Limits
| Action | Limit |
|---|---|
| Login | 1 req/s per API key |
| Place Order | 1200 req / 60s |
| Replace Order | 300 req / 60s |
| Cancel Order | 1200 req / 60s |
| Cancel Orders (Batch) | 1200 req / 60s |
Heartbeat
The server disconnects after 30 seconds of inactivity. Send the raw string ping every ~10 seconds; the server replies pong.
Available Pages
For full rate limits and endpoint details, see the official API documentation: https://apidocliquidity.readme.io/reference/place-order
For all News Feed APIs (REST + WebSocket), see News Feed.
Symbol Format
{EXCHANGE}_{TYPE}_{BASE}_{QUOTE}
| Exchange | Type | Examples |
|---|---|---|
BINANCE | PERP / SPOT | BINANCE_PERP_BTC_USDT, BINANCE_SPOT_BTC_USDT |
OKX | PERP / SPOT | OKX_PERP_BTC_USDT, OKX_SPOT_BTC_USDT |
Channels marked "Perpetual only" reject SPOT symbols with error 11100.
Common Error Codes
REST
| Code | Meaning |
|---|---|
200000 | Success |
2002 | Invalid API authorization |
401018 | Order not found |
401097 | Position quantity is 0 |
401117 | Order already completed |
Market Data WebSocket
| Code | Meaning |
|---|---|
0 | Success |
11100 | Invalid symbol |
11210 | Unauthenticated symbol limit (5) exceeded |
11220 | Authenticated symbol limit (50) exceeded |
11250 | Symbol not currently supported |
11260 | Request rate limit exceeded |