Conventions
These rules apply to every Spot and Futures endpoint unless a section says otherwise.
- Field names are case-sensitive in responses. They are returned exactly as listed here. Most are
snake_case, but a few older responses use other casing (for example the error object'sCodeandMessage). - Timestamps in responses are Unix epoch milliseconds, unless the field is an ISO-8601 string.
- Enums are numbers. For example,
sideis1for Buy and2for Sell, not"BUY". - Errors come back with an HTTP 4xx/5xx status and this body:
{
"Code": 1010,
"Message": "INVALID_SYMBOL"
}
- Symbols: Spot pairs use an underscore (
BTC_USDT). Futures contracts use a hyphen (BTC-USDT).
WebSocket API (Spot)
Connect
URL: wss://api.yourexchange.com/streams
Use the same URL for public and private channels. To use private channels, log in on the open connection first.
Message envelope
Data push
{
"method": "stream",
"channel": "books.BTC_USDT",
"data": [],
"aid": null
}
Every data push has the same shape. When you subscribe to a channel, the server first sends a snapshot of current data on it, then incremental updates.
| Field | Type | Description |
|---|---|---|
| method | string | Always stream |
| channel | string | The channel the data belongs to |
| data | array / object | Channel payload (see each channel) |
| aid | long / null | Account id. Set on private channels, null on public channels. |
Login
Request (bearer token)
{
"method": "login",
"token": "your_bearer_token",
"aid": 0
}
Request (API key)
{
"method": "login",
"api": {
"public_key": "api-public-key",
"timestamp": 1608028160
},
"hmac": "base64-hmac-of-the-api-object"
}
Response
{
"method": "login",
"status": "WS_LOGGED_IN"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| method | string | Yes | login |
| token | string | One of token or api + hmac |
Bearer (JWT) token |
| aid | long | No | Sub-account id to act as. Only honoured with token login. |
| api | object | One of token or api + hmac |
API-key credentials |
| > public_key | string | Yes | API public key |
| > timestamp | long | Yes | Unix epoch seconds. Must not be in the future and must be no more than 45 seconds old. |
| hmac | string | Yes (with api) |
See HMAC |
Possible status values: WS_LOGGED_IN, WS_INVALID_PAYLOAD, WS_INVALID_TIMESTAMP, WS_INVALID_APIKEY, WS_HMAC_VALIDATION_FAILED, WS_UNKNOWN_IP_ADDRESS, WS_INVALID_TOKEN, INVALID_SUB_ACCOUNT.
If the connection is already logged in, a new login is ignored and returns WS_LOGGED_IN. To switch accounts, logout first.
Logout
Request
{ "method": "logout" }
Logout drops all private-channel subscriptions and returns {"method":"logout","status":"WS_LOGGED_OUT"}.
HMAC
- Serialize the
apiobject to compact JSON with keys in this order and no whitespace:{"public_key":"api-public-key","timestamp":1608028160} - Compute the HMAC-SHA256 of that string using your secret key.
- Base64-encode the result.
hmac = Base64(HMAC_SHA256('{"public_key":"api-public-key","timestamp":1608028160}', secretKey))
Subscribe
Request
{
"method": "subscribe",
"channels": ["tickers", "orders.ALL"],
"sss": false
}
Response
{
"method": "subscribe",
"response": [
{ "channel": "tickers", "status": "WS_SUBSCRIBED" },
{ "channel": "orders.ALL", "status": "WS_INVALID_LOGIN" }
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| method | string | Yes | subscribe |
| channels | string[] | Yes | Channels to subscribe to |
| sss | bool | No | "Single symbol subscription". When true, subscribing to a books.* channel first unsubscribes this connection from every other books.* channel. |
Per-channel status values: WS_SUBSCRIBED, WS_INVALID_CHANNEL, WS_INVALID_INTERVAL, WS_INVALID_LOGIN (private channel without login).
A channel you are already subscribed to does not appear in the response.
Unsubscribe
Request
{
"method": "unsubscribe",
"channels": ["tickers", "orders.ALL"]
}
Response
{
"method": "unsubscribe",
"response": [
{ "channel": "tickers", "status": "WS_SUCCESS" },
{ "channel": "orders.ALL", "status": "WS_SUCCESS" }
]
}
Private channels
Log in first. Data on these channels carries the account id in aid.
Balance channel
Channel: wallets
Sends a snapshot on subscribe, then an update whenever a balance changes. Only assets enabled for your exchange are included.
Push
{
"method": "stream",
"channel": "wallets",
"data": [
{
"BTC": [0.5, 0.1, 0, 0, 0, 0, 0],
"USDT": [935.56, 31, 0, 0, 0, 0, 0]
}
],
"aid": 1001
}
data[0] is an object keyed by asset. Each value is:
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Spot available balance |
| 1 | decimal | Spot balance in open orders (frozen) |
| 2 | decimal | Staked balance |
| 3 | decimal | Bonus wallet balance |
| 4 | decimal | Savings wallet balance |
| 5 | decimal | Funding wallet balance |
| 6 | decimal | Locked balance |
Orders channel
Channel: orders.{symbol} or orders.ALL
Sends your open orders on subscribe, then an update on every order event (placed, filled, cancelled, modified).
Push
{
"method": "stream",
"channel": "orders.BTC_USDT",
"data": [
[47106267, 1001, "BTC_USDT", 62982.92, 0.0001, 0.0001, 2, 2, 0, 1713356878402, true, 0, 0, 0, 0, 0, 1713356878402, 0]
],
"aid": 1001
}
| Index | Type | Description |
|---|---|---|
| 0 | long | Order id |
| 1 | long | User id |
| 2 | string | Symbol, e.g. BTC_USDT |
| 3 | decimal | Limit price (0 for market-type orders) |
| 4 | decimal | Size |
| 5 | decimal | Remaining size |
| 6 | int | Order type. See order types. |
| 7 | int | Side, 1 Buy, 2 Sell |
| 8 | decimal | Stop price. For trailing orders that have not activated yet, this is the activation price. |
| 9 | long | Accepted timestamp (ms) |
| 10 | bool | true if the order is open |
| 11 | decimal | Pending quote amount (quote orders) |
| 12 | long | Stop activation timestamp (ms), 0 if not activated |
| 13 | decimal | Initial quote amount (quote orders) |
| 14 | decimal | Trail amount (trailing orders) |
| 15 | decimal | Trail percent (trailing orders) |
| 16 | long | Last-modified timestamp (ms) |
| 17 | decimal | Quote fee reserved |
Trades channel (own trades)
Channel: my-trades.{symbol} or my-trades.ALL
Sends nothing on subscribe. Afterwards, sends each fill of one of your orders.
Push
{
"method": "stream",
"channel": "my-trades.BTC_USDT",
"data": [
["b7512911-5e90-4f8c-b3a6-6d12a5f82a9f", 44240783, "BTC_USDT", 0.01, 8000.0, 80.0, 0.02, 1, 1695901614730, 2]
],
"aid": 1001
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Trade id |
| 1 | long | Order id |
| 2 | string | Symbol |
| 3 | decimal | Executed size |
| 4 | decimal | Execution price |
| 5 | decimal | Total (price × size) |
| 6 | decimal | Fee |
| 7 | int | Your order side, 1 Buy, 2 Sell |
| 8 | long | Timestamp (ms) |
| 9 | int | Taker (aggressor) side, 1 Buy, 2 Sell |
Public channels
Tickers channel
Channel: tickers
Sends every market on subscribe, then updates as prices change.
Push
{
"method": "stream",
"channel": "tickers",
"data": [
["BTC_USDT", 64000.5, 1.25, 1088.2, 69600000.0, 64500.0, 62000.0, 1, "USDT"]
]
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Symbol |
| 1 | decimal | Last price |
| 2 | decimal | 24h change % |
| 3 | decimal | 24h base volume |
| 4 | decimal | 24h quote volume |
| 5 | decimal | 24h high |
| 6 | decimal | 24h low |
| 7 | int | Last execution side, 1 Buy, 2 Sell |
| 8 | string | Symbol group (the quote-asset tab the market belongs to) |
Crypto prices channel
Channel: crypto-prices
Push
{
"method": "stream",
"channel": "crypto-prices",
"data": [["BTC", "64000.5"], ["ETH", "3100.2"]]
}
Each item is [asset, usd_price]. Both values are strings.
Books channel
Channel: books.{symbol} or books.{symbol}.{depth}
depth is 5, 10 or 20. If you leave it out, you get 20 levels. Each push is a full snapshot of the top depth levels.
Push
{
"method": "stream",
"channel": "books.BTC_USDT.5",
"data": [
[[64000.0, 2.0], [63999.5, 1.1]],
[[64000.5, 0.6]]
]
}
| Index | Type | Description |
|---|---|---|
| 0 | array | Bids, [[price, size], …], best first |
| 1 | array | Asks, [[price, size], …], best first |
Books delta channel
Channel: books-delta.{symbol}
On subscribe you get the full book under snapshot. After that, pushes contain only changed levels under updates. A level with size 0 has been removed. The server can also send a fresh snapshot at any time: when one arrives, replace your local book with it.
Snapshot
{
"method": "stream",
"channel": "books-delta.BTC_USDT",
"data": { "snapshot": [[[64000.0, 2.0]], [[64000.5, 0.6]]] }
}
Update
{
"method": "stream",
"channel": "books-delta.BTC_USDT",
"data": { "updates": [[[64000.0, 0]], [[64001.0, 1.4]]] }
}
Trades channel
Channel: trades.{symbol}
Sends recent trades on subscribe, then new trades as they happen.
Push
{
"method": "stream",
"channel": "trades.BTC_USDT",
"data": [
["a592a622-c9e4-4a92-94d9-5893276c8c09", 64000.5, 0.005, 2, 1678964309471]
]
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Trade id |
| 1 | decimal | Price |
| 2 | decimal | Size |
| 3 | int | Taker side, 1 Buy, 2 Sell |
| 4 | long | Timestamp (ms) |
Kline channel
Channel: kline.{symbol}.{interval}
interval is in minutes: 1, 5, 15, 60, 240, 1440, 10080, 43200.
Push
{
"method": "stream",
"channel": "kline.BTC_USDT.1",
"data": [[64000.0, 64010.0, 63990.0, 64005.0, 1.25, 1659070860000, 80006.25]]
}
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Open |
| 1 | decimal | High |
| 2 | decimal | Low |
| 3 | decimal | Close |
| 4 | decimal | Base volume |
| 5 | long | Candle start time (ms) |
| 6 | decimal | Quote volume |
REST API (Spot)
Introduction
Base URL: https://api.yourexchange.com
Authentication
API keys
Create a key pair under Settings → API Keys. Every key must be bound to at least one trusted IP address. A key works only from those IPs.
Each key also has permissions. A request that needs a permission the key does not have fails with API_KEY_PERMISSION_DENIED.
| Permission | Needed for |
|---|---|
| Spot | Trading, orders, balances, deposits, addresses, profile, referrals |
| Withdrawals | crypto-withdraw, withdrawals |
Required headers
| Header | Description |
|---|---|
| x-api-key | API public key |
| x-timestamp | Unix epoch seconds. The request is rejected if it is more than 60 seconds old. |
| x-signature | Base64 HMAC-SHA256 signature (see below) |
| Content-Type | application/json |
Signature
prehash = timestamp + METHOD + requestPath + body
signature = Base64(HMAC_SHA256(prehash, secretKey))
METHODis upper-case:GETorPOST.requestPathis the path including the query string, e.g./lp/v1/ordersor/market/depth?symbol=BTC_USDT&limit=5.bodyis the exact raw JSON string you send. Leave it out when there is no body.
Example: Base64(HMAC_SHA256('1661519941' + 'POST' + '/lp/v1/new-order' + '{"side":1,"symbol":"BTC_USDT","type":2,"size":0.01,"price":60000}', secretKey))
Rate limits
Every endpoint has a weight. Authenticated endpoints count against a budget per API key. Public market/* endpoints count against a budget per client IP. The default budget is 500 points per minute, and the exchange can set a different limit for a key or IP range.
| Weight | Endpoints |
|---|---|
| 2 | Every lp/v1/* endpoint except batch-orders, and every market/* endpoint |
| 10 | lp/v1/batch-orders |
| 15 | Every partners/* endpoint |
Every rate-limited response includes these headers:
| Header | Description |
|---|---|
| X-RateLimit-Per-Minute | Your per-minute budget |
| X-RateLimit-Per-Minute-Used | Points used in the last 60 seconds |
| X-RateLimit-Per-Hour / X-RateLimit-Per-Hour-Used | Only present when an hourly limit is configured |
When you exceed the budget, the API returns HTTP 429 with {"Code":4002,"Message":"RETRY_AFTER_A_MINUTE"}, or RETRY_AFTER_AN_HOUR if you hit the hourly limit.
Spot enums
| Enum | Values |
|---|---|
| Side | 0 Any (filters only), 1 Buy, 2 Sell |
| Order type | 1 Market, 2 Limit (GTC), 3 Stop Market, 4 Stop Limit, 5 Day Only (deprecated), 6 Fill or Kill, 7 Immediate or Cancel, 8 Trailing Stop |
| Order status | -100 Partially filled (closed with a partial fill), 0 Open, 1 Filled, 2 Cancelled |
| Fee source | Main, Bonus |
| Fee type | Base, Quote |
Trade
New order
POST /lp/v1/new-order
Request (size in base)
{
"side": 1,
"symbol": "ETH_USDT",
"type": 2,
"size": 0.3,
"price": 1500,
"client_order_id": "my-ref-001",
"idempotency": true
}
Request (market buy for 100 USDT)
{
"side": 1,
"symbol": "ETH_USDT",
"type": 1,
"quote_amount": 100
}
Request (limit order that expires in 30 seconds)
{
"side": 2,
"symbol": "ETH_USDT",
"type": 2,
"size": 0.3,
"price": 1600,
"cancel_in_sec": 30
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| side | int | Yes | 1 Buy, 2 Sell |
| symbol | string | Yes | e.g. BTC_USDT |
| type | int | Yes | Order type |
| size | decimal | One of size / quote_amount |
Quantity in base asset |
| quote_amount | decimal | One of size / quote_amount |
Amount in quote asset |
| price | decimal | Limit-type orders | Limit price. Ignored for Market, Stop Market and Trailing Stop. |
| stop | decimal | Stop orders | Stop (trigger) price, for Stop Market and Stop Limit |
| trail_amt | decimal | Trailing | Trail distance in quote asset |
| trail_perc | decimal | Trailing | Trail distance in % |
| trail_act_price | decimal | No | Trailing activation price. The trail starts only once the market reaches this price. |
| client_order_id | string | No | Your own reference for the order |
| idempotency | bool | No | With client_order_id, rejects the order with DUPLICATE_CLIENT_ORDER_ID if that id was already used |
| cancel_on_ms | long | No | Limit orders only: auto-cancel at this Unix time (ms). Must be more than 1 second in the future. |
| cancel_in_sec | long | No | Limit orders only: auto-cancel after this many seconds (must be > 1). Cannot be combined with cancel_on_ms. |
Response
{
"order_id": 47107268,
"side": "BUY",
"side_enum": 1,
"order_type": 2,
"size": 0.3,
"filled": 0,
"remaining": 0.3,
"price": 1500,
"filled_price": 0,
"symbol": "ETH_USDT",
"ts": 1713361721055,
"cancel_reason": 0
}
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| side | string | BUY / SELL |
| side_enum | int | 1 Buy, 2 Sell |
| order_type | int | Order type |
| size | decimal | Order size |
| filled | decimal | Filled size |
| remaining | decimal | Unfilled size |
| price | decimal | Limit price |
| filled_price | decimal | Average fill price |
| symbol | string | Symbol |
| ts | long | Accepted timestamp (ms) |
| cancel_reason | int | 0 None, 1 UserRequested, 2 MarketOrderNoLiquidity, 3 ImmediateOrCancel, 4 FillOrKill, 5 BookOrCancel, 6 ValidityExpired, 7 MarketOrderCannotMatchLessThanStepSize, 8 InvalidOrder, 9 SelfTrading, 10 InsufficientBalance, 11 BalancerError, 12 LPC_RISK_VIOLATION, 13 BROKER_MATCH_VIOLATION, 14 MARKET_SLIPPAGE, 15 INVALID_TRAIL_AMOUNT_OR_PERCENT |
Edit orders
POST /lp/v1/update-orders
Request
{
"symbol": "ETH_USDT",
"orders": [
{ "order_id": 43652720, "size": 0.03, "price": 1651 },
{ "order_id": 43652719, "size": 0.04, "price": 1650 }
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol |
| orders | array | Yes | Orders to modify |
| > order_id | long | Yes | Order id (note: order_id, not orderId) |
| > size | decimal | Yes | New size |
| > price | decimal | Yes | New limit price |
Response
[
{
"order_id": 43652720,
"updated": true,
"error_message": null,
"order": {
"symbol": "ETH_USDT",
"order_id": 43652720,
"side": 1,
"order_type": 2,
"size": 0.03,
"price": 1651,
"order_status": 0,
"filled": 0,
"remaining": 0.03,
"filled_price": 0,
"ts": 1713361721055,
"ts_modified": 1713361800000
}
}
]
You get one result per order. updated is false when that order could not be modified, and error_message says why.
Cancel order
POST /lp/v1/cancel-order
Request
{
"symbol": "BTC_USDT",
"order_id": 1018
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol |
| order_id | long | Yes | Order id |
Response
{ "Code": 1000, "Message": "SUCCESS" }
Cancel all orders
POST /lp/v1/cancel-all-orders
Request
{
"symbol": "BTC_USDT",
"side": 0
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol |
| side | int | No | 1 Buy only, 2 Sell only, 0 or omitted for both |
Response
{ "Code": 1000, "Message": "SUCCESS" }
Batch orders
POST /lp/v1/batch-orders (weight 10)
Cancels and places limit (GTC) orders on one symbol in a single request. Cancels run first.
Request
{
"symbol": "BTC_USDT",
"cancel_in_sec": 60,
"sell": {
"cancel_orders": [111, 222],
"new_orders": [[0.5, 64010], [0.7, 64020]]
},
"buy": {
"cancel_orders": [110, 220],
"new_orders": [[0.2, 63990], [0.3, 63980]]
}
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol |
| sell / buy | object | Yes | Send both objects. Either can contain empty arrays. |
| > cancel_orders | long[] | No | Order ids to cancel. No duplicates. At most 100 across both sides. |
| > new_orders | decimal[][] | No | New orders as [size, price]. At most 50 across both sides. |
| cancel_on_ms | long | No | Auto-cancel the new orders at this Unix time (ms) |
| cancel_in_sec | long | No | Auto-cancel the new orders after this many seconds |
Response
{
"symbol": "BTC_USDT",
"sell": {
"cancel_orders": [
{ "order_id": 111, "side": "Sell", "status": "Cancelled", "failure_reason": null }
],
"new_orders": [
{ "order_id": 5001, "side": "Sell", "order_type": "Limit", "status": "Accepted", "size": 0.5, "filled": 0, "remaining": 0.5, "price": 64010, "filled_price": 0, "cancel_failure_reason": null }
]
},
"buy": { "cancel_orders": [], "new_orders": [] },
"error": ""
}
error is non-empty (INVALID_SYMBOL) when your exchange cannot trade the symbol's base or quote asset. In that case cancels still run, but no new orders are placed.
Orders
POST /lp/v1/orders
Order history for one symbol, or your open orders.
Request
{
"symbol": "BTC_USDT",
"side": 0,
"order_id": 0,
"open_orders": false,
"row_count": 1000
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes for history | Symbol. ALL is accepted only when open_orders is true. |
| side | int | No | 1 Buy, 2 Sell, 0 both |
| order_id | long | No | Return only orders with order_id >= this value (history only) |
| open_orders | bool | No | true returns open orders only |
| row_count | int | No | 1–1000, default 1000 |
Response
[
{
"order_id": 47105676,
"symbol": "BTC_USDT",
"size": 0.01590433,
"pending_size": 0,
"open_order": false,
"price": 0,
"ts": 1713351084077,
"side": 2,
"order_type": 1,
"quote_amount": 1000,
"pending_quote_amount": 0.00028337,
"stop_price": 0,
"ts_activated": null,
"trail_amount": 0,
"trail_percent": 0,
"trail_act_price": 0,
"ts_cancel": null,
"ts_modified": 1713351084081,
"order_status": 1,
"filled_size": 0.01590433,
"cancelled_size": 0,
"client_order_id": null,
"quote_fee_reserved": 0
}
]
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| symbol | string | Symbol |
| size | decimal | Original size |
| pending_size | decimal | Unfilled size |
| open_order | bool | true if open |
| price | decimal | Limit price |
| ts | long | Accepted timestamp (ms) |
| side | int | 1 Buy, 2 Sell |
| order_type | int | Order type |
| quote_amount | decimal | Initial quote amount (quote orders) |
| pending_quote_amount | decimal | Unfilled quote amount (quote orders) |
| stop_price | decimal | Stop price |
| ts_activated | long / null | Stop activation timestamp (ms) |
| trail_amount | decimal | Trail amount |
| trail_percent | decimal | Trail percent |
| trail_act_price | decimal | Trailing activation price |
| ts_cancel | long / null | Scheduled or actual cancel time (ms) |
| ts_modified | long / null | Last-modified timestamp (ms) |
| order_status | int | Order status |
| filled_size | decimal | Filled size |
| cancelled_size | decimal | Size cancelled |
| client_order_id | string / null | Your reference |
| quote_fee_reserved | decimal | Quote fee held for the order |
Order detail
POST /lp/v1/order-detail
Returns one order and its fills.
Request
{ "order_id": 47102550 }
Or by your reference
{ "client_order_id": "my-ref-001" }
| Parameter | Type | Required | Description |
|---|---|---|---|
| order_id | long | One of the two | Order id |
| client_order_id | string | One of the two | Your reference |
Response
{
"order_id": 47102550,
"symbol": "BTC_USDT",
"size": 0.01,
"pending_size": 0,
"open_order": false,
"price": 63062.84985,
"ts": 1713350021110,
"side": 1,
"order_type": 1,
"quote_amount": 0,
"pending_quote_amount": 0,
"stop_price": 0,
"ts_activated": null,
"trail_amount": 0,
"trail_percent": 0,
"trail_act_price": 0,
"ts_cancel": null,
"ts_modified": 1713350021125,
"order_status": 1,
"filled_size": 0.01,
"cancelled_size": 0,
"quote_fee_reserved": 0,
"fee": 0.0000276,
"fee_in": "BTC",
"trades": [
{
"trade_id": "583bc795-ffc4-46aa-a7b7-23f617c83466",
"size": 0.01,
"price": 63062.84985,
"total": 630.6284985,
"ts": 1713350021126,
"fee_source": "Main",
"fee_type": "Base",
"fee_ticker": "BTC",
"fee": 0.0000276,
"et": { "ticker": null, "fee": 0, "rate": 0, "contribution": 0 }
}
]
}
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| symbol | string | Symbol |
| size | decimal | Original size |
| pending_size | decimal | Unfilled size |
| open_order | bool | true if open |
| price | decimal | Limit price. For market orders, the average fill price. |
| ts | long | Accepted timestamp (ms) |
| side | int | 1 Buy, 2 Sell |
| order_type | int | Order type |
| quote_amount | decimal | Initial quote amount (quote orders) |
| pending_quote_amount | decimal | Unfilled quote amount (quote orders) |
| stop_price | decimal | Stop price |
| ts_activated | long / null | Stop activation timestamp (ms) |
| trail_amount | decimal | Trail amount |
| trail_percent | decimal | Trail percent |
| trail_act_price | decimal | Trailing activation price |
| ts_cancel | long / null | Scheduled or actual cancel time (ms) |
| ts_modified | long / null | Last-modified timestamp (ms) |
| order_status | int | Order status |
| filled_size | decimal | Filled size |
| cancelled_size | decimal | Size cancelled |
| quote_fee_reserved | decimal | Quote fee held for the order |
| fee | decimal | Total fee across all fills |
| fee_in | string | Asset the fee was charged in |
| trades | array | Fills of this order |
| > trade_id | string | Trade id |
| > size | decimal | Executed size |
| > price | decimal | Execution price |
| > total | decimal | Executed value (quote) |
| > ts | long | Execution timestamp (ms) |
| > fee_source | string | Wallet the fee came from: Main or Bonus |
| > fee_type | string | Base or Quote |
| > fee_ticker | string | Asset the fee was charged in |
| > fee | decimal | Fee amount |
| > et | object | Fee paid in the exchange token: ticker, fee, rate, contribution |
Trades
POST /lp/v1/trades
Your fills (trade history).
Request
{
"symbol": "BTC_USDT",
"order_id": 0,
"row_count": 1000
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol, or ALL |
| order_id | long | No | Return only trades whose order_id >= this value |
| row_count | int | No | 1–1000, default 1000 |
Response
[
{
"trade_id": "cblp3rgtefqs73fepir0",
"order_id": 45,
"symbol": "BTC_USDT",
"size": 2,
"price": 10,
"total": 20,
"side": 1,
"ts": 1659605487000,
"fee_source": "Main",
"fee_type": "Base",
"fee_ticker": "BTC",
"fee": 0.0049995,
"et": { "ticker": "XYZ", "fee": 0.1, "rate": 0.5, "contribution": 0.05 }
}
]
| Field | Type | Description |
|---|---|---|
| trade_id | string | Trade id |
| order_id | long | Your order id |
| symbol | string | Symbol |
| size | decimal | Executed size |
| price | decimal | Execution price |
| total | decimal | Executed value (quote) |
| side | int | Your side, 1 Buy, 2 Sell |
| ts | long | Execution timestamp (ms) |
| fee_source | string | Wallet the fee came from: Main or Bonus |
| fee_type | string | Base or Quote |
| fee_ticker | string | Asset the fee was charged in |
| fee | decimal | Fee amount |
| et | object | Fee paid in the exchange token, if any |
| > ticker | string | Exchange token |
| > fee | decimal | Fee paid in the exchange token |
| > rate | decimal | Conversion rate used |
| > contribution | decimal | Amount of the fee the token covered |
Account
Profile
GET or POST /lp/v1/profile
Response
{
"CID": 12345,
"FirstName": "John",
"LastName": "Doe",
"email": "jh****oe@ex*****.com",
"loginName": "",
"loginNameTS": "1940-01-01T00:00:00",
"joinedOn": "2025-05-20T08:08:15Z",
"is2FAEnabled": false,
"country": "AE",
"mobile": "+971*******12",
"mobileNumberVerificationStatus": "Not Verified",
"kyc": {
"status": "Approved",
"rejection_notes": "",
"level": 1,
"flow_name": "basic",
"no_kyc_rules": { "deposits": false, "withdrawals": false, "trades": false }
},
"kyb": { "status": null, "rejection_notes": null },
"discounts": { "custom": 0, "volume": 0, "nett": 0 },
"referralCode": "T48WNZ",
"findMe": false,
"anti_phishing_code": null,
"accTitle": null,
"accType": "Standard",
"grid_trading": false
}
| Field | Type | Description |
|---|---|---|
| CID | long | Customer id |
| FirstName / LastName | string | Name |
| string | Masked email | |
| loginName / loginNameTS | string / datetime | P2P username and when it was set |
| joinedOn | datetime | Sign-up date |
| is2FAEnabled | bool | 2FA status |
| country | string | ISO country code |
| mobile | string | Masked mobile with dialling code |
| mobileNumberVerificationStatus | string | Verified / Not Verified |
| kyc.no_kyc_rules | object | true means that activity is allowed without KYC |
| kyc.flow_name | string | KYC flow the user went through |
| discounts | object | Fee discounts in %: custom, volume, and nett (the larger of the two) |
| accTitle | string | Sub-account title, null for the main account |
| accType | string | Standard or SubAccount |
| grid_trading | bool | Whether grid trading is enabled for the exchange |
My referrals
GET or POST /lp/v1/my-referrals
Response
{
"my": { "email": "jh****oe@ex*****.com", "cid": 12345, "referer_cid": 0 },
"referrals": [
{ "email": "ma****@pr****.me", "user_id": 12399, "doj": "2023-08-04T09:25:19Z" }
]
}
Wallet
Addresses
GET or POST /lp/v1/addresses
All deposit addresses generated for your account, grouped by asset.
Response
{
"ETH": [
{
"network": "Ethereum",
"address": "0x7ef44B21b95921D1c5fd6b611784b2073491B911",
"address_tag": null,
"blockchain": "ETH"
}
]
}
Address
POST /lp/v1/address
Returns your deposit address for an asset, and creates it if it does not exist yet. Subject to KYC rules and deposit freezes.
Request
{
"asset": "USDT",
"blockchain": "ETH"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| asset | string | Yes | Asset, e.g. USDT |
| blockchain | string | For tokens | Parent chain ticker, e.g. ETH, TRX, BNB |
Response
{
"USDT": [
{
"blockchain": "ETH",
"network": "Ethereum",
"address": "0x7ef44B21b95921D1c5fd6b611784b2073491B911",
"legacy_address": "",
"address_tag": ""
}
]
}
Balance
POST /lp/v1/balance
Request
{ "asset": "BTC" }
| Parameter | Type | Required | Description |
|---|---|---|---|
| asset | string | Yes | Asset ticker, or ALL for every asset |
Response
[
{ "asset": "BTC", "balance": 10233.13468976, "balance_in_trade": 0 }
]
| Field | Type | Description |
|---|---|---|
| asset | string | Asset |
| balance | decimal | Available balance |
| balance_in_trade | decimal | Balance held in open orders |
Deposits
POST /lp/v1/deposits
Request
{
"asset": "BTC",
"from_ts": "2022-11-19",
"to_ts": "2023-01-31"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| asset | string | No | Filter by asset |
| from_ts | string | Yes, unless txn_id or txn_hash is given |
Start date, any parseable date, e.g. 2022-11-19 or 2022-11-19T06:23:04Z |
| to_ts | string | No | End date |
| txn_id | string | No | Find one transaction by id |
| txn_hash | string | No | Find one transaction by chain hash |
Response
[
{
"txn_id": "d1e9…",
"asset": "ETH",
"address": "0xbc72B791471fBFE6E2E900e66C85c2010F5aAeE6",
"amount": 0.5,
"fee": 0,
"txn_hash": "0xb618a7…911f",
"timestamp": "2022-08-20T06:24:57Z",
"confirmations": { "current": 10, "required": 10 },
"explorer_url": "https://etherscan.io/tx/0xb618a7…911f",
"network": "Ethereum",
"parent": "ETH",
"internal": false,
"reject_reason": null,
"status": "Approved",
"approved_date": "2022-08-20T06:30:00Z",
"attachment": null,
"bank": null,
"sender_bank": null,
"pg": null,
"eq_usd": 1550.25
}
]
| Field | Type | Description |
|---|---|---|
| txn_id | string | Transaction id |
| asset | string | Asset |
| address | string | Deposit address |
| amount | decimal | Amount credited |
| fee | decimal | Deposit fee |
| txn_hash | string | Chain hash |
| timestamp | string | Time credited (ISO-8601) |
| confirmations | object | current / required block confirmations |
| explorer_url | string | Block-explorer link |
| network / parent | string | Network name and parent chain ticker |
| internal | bool | true for an off-chain transfer between users |
| status | string | Deposit status |
| reject_reason | string | Set when rejected |
| approved_date | string / null | Approval time |
| bank / sender_bank / pg / attachment | object / string | Fiat deposits only |
| eq_usd | decimal | USD equivalent at deposit time |
Withdrawals
POST /lp/v1/withdrawals (needs the Withdrawals permission)
Request
{
"asset": "USDT",
"from_ts": "2022-11-09",
"to_ts": "2023-01-10"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| asset | string | No | Filter by asset |
| from_ts | string | Yes, unless txn_id or txn_hash is given |
Start date, any parseable date, e.g. 2022-11-09 or 2022-11-09T06:23:04Z |
| to_ts | string | No | End date |
| txn_id | string | No | Find one transaction by id |
| txn_hash | string | No | Find one transaction by chain hash |
Response
[
{
"txn_id": "a77c…",
"asset": "USDT",
"address": "TJ7m5YEU3QGKdLVCuPZGTkNea14QfYgfvu",
"amount": 10,
"eq_usd": 10,
"fee": 1,
"txn_hash": null,
"timestamp": "2023-01-04T07:04:37Z",
"status": "Rejected",
"reject_reason": "test",
"explorer_url": "https://tronscan.org/#/transaction/",
"network": "Tron",
"parent": "TRX",
"fiat_bank": null,
"internal": false,
"client_ref_id": "0011001",
"pg": null
}
]
| Field | Type | Description |
|---|---|---|
| txn_id | string | Transaction id |
| asset | string | Asset |
| address | string | Destination address |
| amount | decimal | Amount withdrawn |
| eq_usd | decimal | USD equivalent at request time |
| fee | decimal | Withdrawal fee |
| txn_hash | string / null | Chain hash, once broadcast |
| timestamp | string | Request time (ISO-8601) |
| status | string | Pending, Submitted, Rejected, Approved, Processed |
| reject_reason | string / null | Set when rejected |
| explorer_url | string | Block-explorer link |
| network / parent | string | Network name and parent chain ticker |
| fiat_bank | object / null | Bank details (fiat withdrawals only) |
| internal | bool | true for an off-chain transfer to another user |
| client_ref_id | string / null | The value you sent to Crypto withdraw |
| pg | object / null | Payment-gateway details (fiat withdrawals only) |
Crypto withdraw
POST /lp/v1/crypto-withdraw (needs the Withdrawals permission)
Request
{
"asset": "USDT",
"blockchain": "ETH",
"address": "0x595f1c56eF8A26a33062a8C7Bf831caD37938865",
"address_tag": "",
"amount": 10,
"client_ref_id": "0011001"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| asset | string | Yes | Asset |
| blockchain | string | For tokens | Parent chain ticker |
| address | string | Yes | Destination address |
| address_tag | string | For memo chains | Memo / destination tag (XRP, XLM, …) |
| amount | decimal | Yes | Amount |
| client_ref_id | string | No | Your reference. It is returned in Withdrawals. |
Response
{ "txn_id": "a77c0d1e-…" }
Market data
Market endpoints are public. The exchange is resolved from the request's Referer / host. All have weight 2.
Symbols
GET /market/symbols
Response
[
{
"symbol": "BTC_USDT",
"min_size": "0.0005",
"min_price": "0.000001",
"min_order_total": "15",
"active": true,
"maker_fee": "0.25",
"taker_fee": "0.5"
}
]
| Field | Type | Description |
|---|---|---|
| symbol | string | Symbol |
| min_size | string | Minimum order size (base) |
| min_price | string | Minimum price / price tick |
| min_order_total | string | Minimum order value (quote) |
| active | bool | Trading enabled |
| maker_fee / taker_fee | string | Fees in % |
Markets
GET /market/markets or GET /market/markets/{symbol}
Response
{
"BTC_USDT": {
"last_price": 24867.48762,
"lowest_ask": 24913.9891,
"highest_bid": 24867.48762,
"base_volume": 0.05,
"high_24hr": 24913.9891,
"low_24hr": 24500.1,
"change_perc_24hr": 1.25
}
}
| Field | Type | Description |
|---|---|---|
| last_price | decimal | Last traded price |
| lowest_ask / highest_bid | decimal | Best ask / bid |
| base_volume | decimal | 24h volume (base) |
| high_24hr / low_24hr | decimal | 24h high / low |
| change_perc_24hr | decimal | 24h change %, 2 decimal places |
Depth
GET /market/depth?symbol={symbol}&limit={limit}
| Parameter | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Symbol |
| limit | int | No | Levels per side: 5, 10, 20, 50, 100, 500, 1000. Values below 5 become 5. |
Response
{
"ts": 1678970255625,
"bids": [[24867.48762, 0.065], [24867.47763, 0.0034]],
"asks": [[24913.9891, 0.0456], [24913.99911, 0.1506]]
}
Trades
GET /market/trades/{symbol}
Returns the latest 50 public trades.
Response
[
["a592a622-c9e4-4a92-94d9-5893276c8c09", 24867.48762, 0.005, 2, 1678964309471]
]
| Index | Type | Description |
|---|---|---|
| 0 | string | Trade id |
| 1 | decimal | Price |
| 2 | decimal | Size |
| 3 | int | Taker side, 1 Buy, 2 Sell |
| 4 | long | Timestamp (ms) |
Kline
GET /market/charts?base={base}"e={quote}&ts={ts}&interval={interval}&limit={limit}
| Parameter | Type | Required | Description |
|---|---|---|---|
| base | string | Yes | Base asset, e.g. BTC |
| quote | string | Yes | Quote asset, e.g. USDT |
| ts | long | Yes | End time (ms). Candles are returned up to this time. |
| interval | int | Yes | Minutes: 1, 5, 15, 60, 240, 1440, 10080, 43200 |
| limit | int | No | Number of candles, 1–1000, default 250 |
| csv | bool | No | true returns CSV instead of JSON |
Response
[
{ "time": 1678838400000, "open": 0.082573, "close": 0.082573, "high": 0.082573, "low": 0.082573, "volume": 0 }
]
Candles are newest first. volume is in the base asset.
Partnerships
These endpoints are for business partners only. They use a partner API key, which is separate from a user API key. They use the same x-api-key / x-timestamp / x-signature headers and signature. Each partner key has an access mode: Read keys can call every endpoint except internal-transfer, which needs a Write key. Every partner endpoint has weight 15.
Balances (snapshot)
GET or POST /partners/balances
Positive balances of every user on your exchange for one asset, keyed by user id.
Request
{ "asset": "USDT" }
Response
{
"103906": 1048.3704143,
"165891": 1004.76739387
}
Open orders
GET or POST /partners/open-orders
Request
{ "symbol": "BNB_USDC" }
Response
[
{
"pair": "BNB_USDC",
"order_id": 2235001,
"size": 0.1,
"pending_size": 0.095,
"price": 961.1,
"user_id": 165891,
"side": "sell",
"order_type": "Limit"
}
]
Addresses
GET or POST /partners/addresses
Request
{
"email": "john@example.com",
"asset": "USDT",
"blockchain": "ETH"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| string | Yes | User's email | |
| asset | string | No | Filter by asset |
| blockchain | string | No | Filter by parent chain. Only applies together with asset. |
Response
{
"USDT": [
{
"network": "Ethereum",
"address": "0x375Ca4C3d29182dBF0B212Ee308123927233F4a0",
"blockchain": "ETH",
"address_tag": "",
"legacy_address": null
}
]
}
Internal transfer
POST /partners/internal-transfer (Write key)
Moves funds off-chain between two users on your exchange.
Request
{
"from_email": "john@example.com",
"to_email": "paul@example.com",
"asset": "USDT",
"amount": 15.5
}
Response
{
"type": "Crypto",
"txn_hash": "0153583c-b4ff-43ad-8c33-8c7dbbfade92"
}
Referrals
GET or POST /partners/referrals
Request
{ "email": "john@example.com" }
Response
[
{ "email": "mary@example.com", "doj": "2023-08-04T09:25:19Z" }
]
Profile
GET or POST /partners/profile
Request
{ "email": "john@example.com" }
Response
{
"id": 12345,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"pass_key": false,
"login_name": "",
"login_name_ts": null,
"joined_on": "2025-05-20T08:08:15Z",
"is_2fa_enabled": false,
"country": "AE",
"group_name": null,
"mobile": "*******12",
"mobile_country_code": "+971",
"phone_verification": false,
"mobile_number_verification_status": "Not Verified",
"dob": "1990-01-31",
"kyc": {
"status": "Approved",
"status_pro": "None",
"status_micropayments": false,
"rejection_notes": "",
"level": 1,
"flow_name": "",
"no_kyc_rules": { "deposits": false, "withdrawals": false, "trades": false },
"address": { "street": null, "city": null, "postcode": null, "state": null },
"kyc_data": [ { "field_name": "Nationality", "field_value": "AE" } ],
"pro": null,
"risk_ques": 0
},
"kyb": { "status": null, "rejection_notes": null },
"discounts": { "group": null, "custom": 0, "volume": 0, "nett": 0, "locking_tier": "Tier 1" },
"referral_code": "T48WNZ",
"referral": { "code": "T48WNZ", "url": "https://yourexchange.com/ref/T48WNZ" },
"find_me": false,
"anti_phishing_code": null,
"acc_title": null,
"acc_type": "Standard",
"sa_type": null,
"grid_trading": false,
"auto_buying": false,
"admin_session": false,
"kyc_provider_name": "None",
"adhoc_addresses": false,
"crypto_alerts": false,
"requires_2fa": { "deposits": false, "withdrawals": false, "trading": false }
}
| Field | Type | Description |
|---|---|---|
| id | long | User id |
| string | Full (unmasked) email | |
| mobile / mobile_country_code | string | Masked number and dialling code (returned separately) |
| phone_verification | bool | Whether phone verification is required |
| dob | string | Date of birth yyyy-MM-dd, or null |
| kyc.status_pro / status_micropayments / pro | — | Pro-KYC status, micro-payment verification, and the matched Pro-KYC rule (provider, kyc_level, flow_name, flow_title, micro_payment, crypto_deposit, crypto_withdrawal, cards_deposit, trading) |
| kyc.risk_ques | int | Number of unanswered risk questions |
| discounts.group / locking_tier | string | Fee group and locking tier |
| referral | object | code and full referral url |
| acc_type / sa_type | string | Account type, and the sub-account purpose (Saving Plan, GridTrading Bots, Others) |
| requires_2fa | object | Whether 2FA is mandatory for deposits / withdrawals / trading |
| kyc_provider_name | string | KYC provider for the user's country |
Sub-accounts are rejected with FEATURE_DISABLED_FOR_SUBACCOUNT.
WebSocket API (Futures)
Connect
URL: wss://futures-api.yourexchange.com/streams
Use the same URL for public and private channels. To use private channels, log in on the open connection first.
Ping
{ "method": "ping" }
Pong
{ "method": "pong" }
Message envelope (Futures)
Data push
{
"method": "stream",
"channel": "positions",
"data": [],
"aid": 1318659424
}
Every data push has the same shape. When you subscribe to a channel, the server first sends a snapshot of current data on it, then incremental updates.
| Field | Type | Description |
|---|---|---|
| method | string | Always stream |
| channel | string | The channel the data belongs to |
| data | array / object | Channel payload (see each channel) |
| aid | long / null | Account id. Set on private channels, null on public channels. |
Login (Futures)
Request (bearer token, trading on a prop/sub account)
{
"method": "login",
"token": "your_bearer_token",
"aid": 1318659424
}
Request (API key)
{
"method": "login",
"api": { "public_key": "api-public-key", "timestamp": 1608028160 },
"hmac": "base64-hmac-of-the-api-object",
"aid": 1318659424
}
Response
{ "method": "login", "status": "WS_LOGGED_IN" }
| Parameter | Type | Required | Description |
|---|---|---|---|
| method | string | Yes | login |
| token | string | One of token or api + hmac |
Bearer (JWT) token |
| api | object | One of token or api + hmac |
API-key credentials |
| > public_key | string | Yes | API public key |
| > timestamp | long | Yes | Unix epoch seconds. Must not be in the future and must be no more than 45 seconds old. |
| hmac | string | Yes (with api) |
See HMAC (Futures) |
| aid | long | No | Futures account id to stream |
A user can own several futures accounts (for example prop evaluation and funded accounts). Pass aid to choose which one the connection streams. It works with both token and API-key login. If you omit aid, the connection uses the account the token or API key belongs to. If the account does not belong to the user, login fails with SUB_ACCOUNT_NOT_FOUND.
Possible status values: WS_LOGGED_IN, WS_INVALID_PAYLOAD, WS_INVALID_TIMESTAMP, WS_INVALID_APIKEY, WS_HMAC_VALIDATION_FAILED, WS_UNKNOWN_IP_ADDRESS, WS_INVALID_TOKEN, SUB_ACCOUNT_NOT_FOUND.
Logging in again on the same connection switches accounts: all private subscriptions are cleared, so resubscribe afterwards.
Logout (Futures)
Request
{ "method": "logout" }
Response
{ "method": "logout", "status": "WS_LOGGED_OUT" }
Logout drops all private-channel subscriptions.
HMAC (Futures)
- Serialize the
apiobject to compact JSON with keys in this order and no whitespace:{"public_key":"api-public-key","timestamp":1608028160} - Compute the HMAC-SHA256 of that string using your secret key.
- Base64-encode the result.
hmac = Base64(HMAC_SHA256('{"public_key":"api-public-key","timestamp":1608028160}', secretKey))
The comparison on Futures is case-insensitive.
Subscribe (Futures)
Request
{
"method": "subscribe",
"channels": ["tickers", "positions", "orders.ALL"]
}
Response
{
"method": "subscribe",
"response": [
{ "channel": "tickers", "status": "WS_SUBSCRIBED" },
{ "channel": "positions", "status": "WS_SUBSCRIBED" },
{ "channel": "orders.ALL", "status": "WS_SUBSCRIBED" }
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| method | string | Yes | subscribe |
| channels | string[] | Yes | Channels to subscribe to |
Per-channel status values: WS_SUBSCRIBED, WS_INVALID_CHANNEL, WS_INVALID_INTERVAL, WS_INVALID_LOGIN (private channel without login), CUSTOMER_NOT_FOUND.
A channel you are already subscribed to does not appear in the response.
Unsubscribe (Futures)
Request
{
"method": "unsubscribe",
"channels": ["tickers", "orders.ALL"]
}
Response
{
"method": "unsubscribe",
"response": [
{ "channel": "tickers", "status": "WS_SUCCESS" },
{ "channel": "orders.ALL", "status": "WS_SUCCESS" }
]
}
Private channels (Futures)
Each push's aid is the account id. Several array payloads also include the account title and id.
Balance channel (Futures)
Channel: wallets
Push
{
"method": "stream",
"channel": "wallets",
"data": {
"USDT": [10000, -12.5, 9987.5, 20.1, 150.3, 9817.1, "Main", 1318659424, 0, 0, 35.2]
},
"aid": 1318659424
}
data is an object keyed by settlement asset. Unlike Spot, it is not wrapped in an array.
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Wallet balance |
| 1 | decimal | Unrealized PnL |
| 2 | decimal | Margin balance (wallet + uPnL) |
| 3 | decimal | Order margin |
| 4 | decimal | Position margin |
| 5 | decimal | Available balance |
| 6 | string | Account title |
| 7 | long | Account id |
| 8 | decimal | Reserved, always 0 |
| 9 | decimal | Reserved, always 0 |
| 10 | decimal | Realized PnL |
Margin settings channel
Channel: margin-settings.{contract}
Push
{
"method": "stream",
"channel": "margin-settings.BTC-USDT",
"data": [1000000, 2, 1, 50, 10, "Main", 1318659424, 8190.99],
"aid": 1318659424
}
| Index | Type | Description |
|---|---|---|
| 0 | long | Risk limit (max position value) |
| 1 | decimal | Initial margin % |
| 2 | decimal | Maintenance margin % |
| 3 | decimal | Max leverage |
| 4 | decimal | Current leverage. Default 10 if never set. |
| 5 | string | Account title |
| 6 | long | Account id |
| 7 | decimal | Used limit (current position value counted against the risk limit) |
Orders channel (Futures)
Channel: orders.{contract} or orders.ALL
Sends open orders on subscribe, then an update on every change.
Push
{
"method": "stream",
"channel": "orders.BTC-USDT",
"data": [
[5681770932, 1318659424, "BTC-USDT", 81909.9, 0.001, 0.001, 2, 1, 0, 1744267256387, true, 0, 0, 0, "Main", 1318659424]
],
"aid": 1318659424
}
| Index | Type | Description |
|---|---|---|
| 0 | long | Order id |
| 1 | long | Account id that owns the order |
| 2 | string | Contract |
| 3 | decimal | Limit price |
| 4 | decimal | Size |
| 5 | decimal | Remaining size |
| 6 | int | Order type: 1 Market, 2 Limit, 3 Stop Market, 4 Stop Limit, 5 Day Only, 6 FOK, 7 IOC, 100 Take Profit, 101 Stop Loss |
| 7 | int | Side, 1 Buy, 2 Sell |
| 8 | decimal | Stop price |
| 9 | long | Accepted timestamp (ms) |
| 10 | bool | true if open |
| 11 | decimal | Quote amount |
| 12 | long | Stop activation timestamp (ms), 0 if not activated |
| 13 | decimal | User quote amount |
| 14 | string | Account title |
| 15 | long | Account id |
User orders channel
Channel: my-orders.{contract} or my-orders.ALL
On subscribe, sends your orders from the last 7 days (open and closed). After that, sends updates.
Push
{
"method": "stream",
"channel": "my-orders.BTC-USDT",
"data": [
["BTC-USDT", 0.001, 81909.9, 0.001, 0, 81909.9, "Market", 5681770932, "Filled", 1744267256387, "Main", 1318659424, "Buy"]
],
"aid": 1318659424
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Contract |
| 1 | decimal | Size |
| 2 | decimal | Price (for market orders, the average fill price) |
| 3 | decimal | Filled size |
| 4 | decimal | Stop price |
| 5 | decimal | Average fill price |
| 6 | string | Order type, e.g. Market, Limit, StopLimit, TakeProfit, StopLoss |
| 7 | long | Order id |
| 8 | string | Status: Pending, Partially Filled, Filled, Cancelled |
| 9 | long | Accepted timestamp (ms) |
| 10 | string | Account title |
| 11 | long | Account id |
| 12 | string | Side, Buy / Sell |
User trades channel
Channel: my-trades.{contract} or my-trades.ALL
On subscribe, sends your fills from the last 7 days. After that, sends new fills.
Push
{
"method": "stream",
"channel": "my-trades.BTC-USDT",
"data": [
["b5ab845d-4b6d-4abb-9976-e4c3a2abd552", 81909.9, 0.001, 2, 1744267256000, 5681770932, "BTC-USDT", 81.9099, 0.20477475, "Main", 1318659424, "Opened", 0, "e9f02a59-75f9-43ea-99d5-07bae198e01a"]
],
"aid": 1318659424
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Trade id |
| 1 | decimal | Price |
| 2 | decimal | Size |
| 3 | int | Execution side, 1 Buy, 2 Sell |
| 4 | long | Timestamp (ms) |
| 5 | long | Order id |
| 6 | string | Contract |
| 7 | decimal | Executed value (price × size) |
| 8 | decimal | Fee |
| 9 | string | Account title |
| 10 | long | Account id |
| 11 | string | Position effect, e.g. Opened, Closed |
| 12 | decimal | Realized PnL of this fill |
| 13 | string | Position id |
Positions channel
Channel: positions
Push
{
"method": "stream",
"channel": "positions",
"data": [
["e9f02a59-75f9-43ea-99d5-07bae198e01a", "BTC-USDT", -0.001, 81.9437, 81909.9, 81943.7, 97472.781, 16.15008075, 6.14, -0.0338, -0.20477475, 0, 0, "USDT", -0.0129, 17.582617, 0, 0, -0.21, 5, "Main", 1318659424, 0, 0.001, 0, 0.20477475, 0]
],
"aid": 1318659424
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Position id |
| 1 | string | Contract |
| 2 | decimal | Size. Negative means short. |
| 3 | decimal | Position value |
| 4 | decimal | Average entry price |
| 5 | decimal | Mark price |
| 6 | decimal | Liquidation price |
| 7 | decimal | Position margin |
| 8 | decimal | Effective leverage |
| 9 | decimal | Unrealized PnL |
| 10 | decimal | Realized PnL (total) |
| 11 | decimal | ADL ranking |
| 12 | int | Status, 0 Open, 1 Closed, 2 Liquidated |
| 13 | string | Settlement asset |
| 14 | decimal | ROE (PnL % × effective leverage / 100) |
| 15 | decimal | Max removable margin |
| 16 | long | Close order id |
| 17 | decimal | Close order limit price |
| 18 | decimal | PnL % |
| 19 | decimal | Current leverage |
| 20 | string | Account title |
| 21 | long | Account id |
| 22 | decimal | Total bought |
| 23 | decimal | Total sold |
| 24 | decimal | Realized PnL: trading earnings |
| 25 | decimal | Realized PnL: fees paid (positive = cost) |
| 26 | decimal | Realized PnL: funding (negative = you paid) |
Public channels (Futures)
Tickers channel (Futures)
Channel: tickers (futures contracts only), or symbols (futures contracts plus the exchange's Spot markets, if Spot is enabled)
Push
{
"method": "stream",
"channel": "tickers",
"data": [
["BTC-USDT", 76131.7, 1.25, 63056.658, 4853043013.77, 77509.9, 75803.3, 2, "BTC", "USDT", "USDT", "Crypto", 50]
]
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Contract |
| 1 | decimal | Last price |
| 2 | decimal | 24h change % |
| 3 | decimal | 24h base volume |
| 4 | decimal | 24h quote volume |
| 5 | decimal | 24h high |
| 6 | decimal | 24h low |
| 7 | int | Last execution side, 1 Buy, 2 Sell |
| 8 | string | Base asset |
| 9 | string | Quote asset |
| 10 | string | Settlement asset ("" for Spot rows on symbols) |
| 11 | string | Instrument type, e.g. Crypto, or Spot on symbols |
| 12 | decimal | Max leverage (0 for Spot rows) |
Funding rate channel
Channel: funding-rate.{contract}
Push
{
"method": "stream",
"channel": "funding-rate.BTC-USDT",
"data": [0.0001, 0.00012, 1744185900000, 1744214700000]
}
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Current funding rate |
| 1 | decimal | Predicted next rate (can be 0 for externally priced contracts) |
| 2 | long | Rate timestamp (ms) |
| 3 | long | Next funding time (ms) |
Mark price channel
Channel: mark-price.{contract}
Push
{
"method": "stream",
"channel": "mark-price.BTC-USDT",
"data": [76199.8, 76160.455]
}
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Mark price |
| 1 | decimal | Index price |
Stats channel
Channel: stats.{contract}
Push
{
"method": "stream",
"channel": "stats.BTC-USDT",
"data": ["BTC-USDT", 51832096.27, 15400000.5]
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Contract |
| 1 | decimal | 24h quote (notional) volume |
| 2 | decimal | Open interest value (notional) |
Books channel (Futures)
Channel: books.{contract} or books.{contract}.{depth}
depth is 5, 10 or 20. If you leave it out, you get 20 levels. Each push is a full snapshot of the top depth levels.
Push
{
"method": "stream",
"channel": "books.BTC-USDT.5",
"data": [
[[76159.8, 5.33], [76159.7, 0.468]],
[[76159.9, 6.0], [76160.0, 1.25]]
],
"aid": null
}
| Index | Type | Description |
|---|---|---|
| 0 | array | Bids, [[price, size], …], best (highest) first |
| 1 | array | Asks, [[price, size], …], best (lowest) first |
Books delta channel (Futures)
Channel: books-delta.{contract}
On subscribe you get the full book under snapshot. After that, pushes contain only changed levels under updates. A level with size 0 has been removed. The server can also send a fresh snapshot at any time: when one arrives, replace your local book with it.
Snapshot
{
"method": "stream",
"channel": "books-delta.BTC-USDT",
"data": {
"snapshot": [
[[76159.8, 5.33], [76159.7, 0.468]],
[[76159.9, 6.0], [76160.0, 1.25]]
]
},
"aid": null
}
Update
{
"method": "stream",
"channel": "books-delta.BTC-USDT",
"data": {
"updates": [
[[76159.8, 0], [76159.6, 2.1]],
[[76159.9, 4.5]]
]
},
"aid": null
}
| Field | Type | Description |
|---|---|---|
| snapshot / updates | array | [bids, asks] |
| > [0] | array | Bids, [[price, size], …] |
| > [1] | array | Asks, [[price, size], …] |
Trades channel (Futures)
Channel: trades.{contract}
Push
{
"method": "stream",
"channel": "trades.BTC-USDT",
"data": [
["26f55bb3-7a90-4907-9ad0-bbc9f4a35587", 76170.1, 0.055, 1, 1744199812257, 120.5, 0.16]
]
}
| Index | Type | Description |
|---|---|---|
| 0 | string | Trade id |
| 1 | decimal | Price |
| 2 | decimal | Size |
| 3 | int | Taker side, 1 Buy, 2 Sell |
| 4 | long | Timestamp (ms) |
| 5 | decimal | 24h price change (absolute) |
| 6 | decimal | 24h price change % |
Kline channel (Futures)
Channel: kline.{contract}.{interval}
interval is in minutes: 1, 5, 15, 60, 240, 1440, 10080, 43200.
Push
{
"method": "stream",
"channel": "kline.BTC-USDT.60",
"data": [[81826, 81900, 81800, 81850, 12.5, 1744272000000, 1023125.0]]
}
| Index | Type | Description |
|---|---|---|
| 0 | decimal | Open |
| 1 | decimal | High |
| 2 | decimal | Low |
| 3 | decimal | Close |
| 4 | decimal | Base volume |
| 5 | long | Candle start time (ms) |
| 6 | decimal | Quote volume |
REST API (Futures)
Introduction (Futures)
Base URL: the Futures API host, e.g. https://futures-api.yourexchange.com
Contracts use a hyphen: BTC-USDT.
Authentication (Futures)
API keys (Futures)
Create a key pair under Settings → API Keys and enable the Futures permission on it. Without that permission every call returns HTTP 401 with API_KEY_PERMISSION_DENIED. The key must be bound to at least one trusted IP address, and it works only from those IPs. Requests from any other IP return HTTP 401 with INVALID_IP_ADDRESS.
Required headers (Futures)
| Header | Description |
|---|---|
| x-api-key | API public key |
| x-timestamp | Unix epoch seconds. The request is rejected if it is more than 60 seconds old. |
| x-signature | Base64 HMAC-SHA256 signature (see below) |
| Content-Type | application/json |
Signature (Futures)
prehash = timestamp + METHOD + requestPath + body
signature = Base64(HMAC_SHA256(prehash, secretKey))
METHODis upper-case:GETorPOST.requestPathis the path including the query string, e.g./lp/v1/orders.bodyis the exact raw JSON string you send. Leave it out when there is no body.
Example: Base64(HMAC_SHA256('1744267256' + 'POST' + '/lp/v1/new-order' + '{"side":1,"symbol":"BTC-USDT","type":2,"size":0.01,"price":76000}', secretKey))
Error response (bad signature)
{ "Code": 1047, "Message": "INVALID_HEADER_X_SIGNATURE" }
Choosing the account (aid)
Every lp/v1 request body accepts an optional aid (account id). If you leave it out, the request uses the API key's own account. If you set it, the account must belong to the same exchange, or the request fails with ACCOUNT_NOT_FOUND.
Futures enums
| Enum | Values |
|---|---|
| Side | 0 Any (filters only), 1 Buy, 2 Sell |
| Order type | 1 Market, 2 Limit (GTC), 3 Stop Market, 4 Stop Limit, 5 Day Only, 6 Fill or Kill, 7 Immediate or Cancel |
| Trigger type | 0 Last price, 1 Mark price, 2 Index price |
| Order status | 0 Pending, 1 Filled, 2 Cancelled, 3 Partially filled, 4 Accepted |
Trade (Futures)
New order (Futures)
POST /lp/v1/new-order
Request
{
"aid": 1318659424,
"side": 1,
"symbol": "BTC-USDT",
"type": 2,
"size": 0.01,
"price": 76000,
"tp_price": 80000,
"sl_price": 74000,
"post_only": true,
"client_order_id": "bot-123"
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id (see aid) |
| side | int | Yes | 1 Buy, 2 Sell |
| symbol | string | Yes | Contract, e.g. BTC-USDT |
| type | int | Yes | Order type |
| size | decimal | One of size / quote_amount |
Contracts / base quantity |
| quote_amount | decimal | Market orders only | Order value in quote. Fails with QUOTE_AMOUNT_ONLY_FOR_MARKET_ORDERS on other types. |
| price | decimal | Limit-type orders | Limit price. Ignored for Market and Stop Market. |
| stop | decimal | Stop orders | Trigger price, for Stop Market and Stop Limit |
| trigger_type | int | No | What the stop triggers on: 0 Last (default), 1 Mark, 2 Index |
| closeon_trigger | bool | No | Close-on-trigger stop: it only reduces the position |
| tp_price | decimal | No | Take-profit price, attached as a bracket |
| sl_price | decimal | No | Stop-loss price, attached as a bracket |
| post_only | bool | No | Reject if the order would take liquidity |
| reduce_only | bool | No | Only reduce an existing position |
| client_order_id | string | No | Your reference |
Response
{
"order_id": 5681770932,
"side": "BUY",
"order_type": 2,
"size": 0.01,
"filled": 0,
"remaining": 0.01,
"price": 76000,
"filled_price": 0,
"order_status": "Accepted",
"cancel_reason": "None"
}
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| side | string | BUY / SELL |
| order_type | int | Order type |
| size / filled / remaining | decimal | Sizes |
| price | decimal | Limit price |
| filled_price | decimal | Average fill price |
| order_status | string | None, Accepted, PartiallyFilled, Filled, Cancelled, Failed |
| cancel_reason | string | e.g. None, ImmediateOrCancel, FillOrKill, BookOrCancel, InsufficientBalance, SelfTrading |
Bulk order
POST /lp/v1/bulk-order
Places several orders on one contract in a single request.
Request
{
"aid": 1318659424,
"symbol": "BTC-USDT",
"orders": [
{ "side": 1, "type": 2, "size": 0.01, "price": 75900 },
{ "side": 2, "type": 2, "size": 0.01, "price": 76100, "post_only": true }
]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| symbol | string | Yes | Contract. It applies to every order. |
| orders | array | Yes | Orders to place |
| > side | int | Yes | 1 Buy, 2 Sell |
| > type | int | Yes | Order type |
| > size | decimal | One of size / quote_amount |
Contracts / base quantity |
| > quote_amount | decimal | Market orders only | Order value in quote |
| > price | decimal | Limit-type orders | Limit price |
| > stop | decimal | Stop orders | Trigger price |
| > trigger_type | int | No | 0 Last (default), 1 Mark, 2 Index |
| > closeon_trigger | bool | No | Close-on-trigger stop |
| > tp_price | decimal | No | Take-profit price |
| > sl_price | decimal | No | Stop-loss price |
| > post_only | bool | No | Reject if the order would take liquidity |
| > reduce_only | bool | No | Only reduce an existing position |
| > client_order_id | string | No | Your reference |
Response
{
"5681770932": {
"order_id": 5681770932,
"side": "BUY",
"order_type": 2,
"size": 0.01,
"filled": 0,
"remaining": 0.01,
"price": 75900,
"filled_price": 0,
"order_status": "Accepted",
"cancel_reason": "None"
},
"5681770933": {
"order_id": 5681770933,
"side": "SELL",
"order_type": 2,
"size": 0.01,
"filled": 0,
"remaining": 0.01,
"price": 76100,
"filled_price": 0,
"order_status": "Accepted",
"cancel_reason": "None"
}
}
The response is an object keyed by order id:
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| side | string | BUY / SELL |
| order_type | int | Order type |
| size / filled / remaining | decimal | Sizes |
| price | decimal | Limit price |
| filled_price | decimal | Average fill price |
| order_status | string | None, Accepted, PartiallyFilled, Filled, Cancelled, Failed |
| cancel_reason | string | e.g. None, ImmediateOrCancel, FillOrKill, BookOrCancel, InsufficientBalance, SelfTrading |
Cancel order (Futures)
POST /lp/v1/cancel-order
Request
{
"aid": 1318659424,
"Symbol": "BTC-USDT",
"OrderId": 5681770932
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| Symbol | string | Yes | Contract |
| OrderId | long | Yes | Order id |
Response
{
"order_id": 5681770932,
"side": "BUY",
"order_type": 2,
"size": 0.01,
"filled": 0,
"remaining": 0.01,
"price": 76000,
"filled_price": 0,
"order_status": "Cancelled",
"cancel_reason": null
}
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| side | string | BUY / SELL |
| order_type | int | Order type |
| size / filled / remaining | decimal | Sizes at cancel time |
| price | decimal | Limit price |
| filled_price | decimal | Average fill price |
| order_status | string | Cancelled on success |
| cancel_reason | null | Not set on this endpoint |
Cancel orders (by id)
POST /lp/v1/cancel-orders
Request
{
"aid": 1318659424,
"Symbol": "BTC-USDT",
"OrderIds": [5681770932, 5681770933]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| Symbol | string | Yes | Contract |
| OrderIds | long[] | Yes | Order ids to cancel (at least one) |
Response
{ "Code": 1000, "Message": "SUCCESS" }
Cancel all orders (Futures)
POST /lp/v1/cancel-my-orders
Request
{
"aid": 1318659424,
"Symbol": "BTC-USDT",
"Side": 0
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| Symbol | string | Yes | Contract |
| Side | int | No | 1 Buy, 2 Sell, 0 both |
Response
{ "Code": 1000, "Message": "SUCCESS" }
Cancel by price levels
POST /lp/v1/cancel-user-price-points
Cancels your orders resting at the given prices.
Request
{
"aid": 1318659424,
"Symbol": "BTC-USDT",
"Prices": [75900, 76100]
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| Symbol | string | Yes | Contract |
| Prices | decimal[] | Yes | Price levels whose orders should be cancelled (at least one) |
Response
{ "Code": 1000, "Message": "SUCCESS" }
Orders (Futures)
POST /lp/v1/orders
Request
{
"aid": 1318659424,
"symbol": "BTC-USDT",
"side": 0,
"order_id": 0,
"open_orders": false,
"row_count": 1000
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| symbol | string | Yes for history | Contract. ALL is accepted only when open_orders is true. |
| side | int | No | 1 Buy, 2 Sell, 0 both |
| order_id | long | No | Return only orders with order_id >= this value (history only) |
| open_orders | bool | No | true returns open orders only |
| row_count | int | No | 1–1000, default 1000 |
Response
[
{
"order_id": 5681770932,
"symbol": "BTC-USDT",
"size": 0.001,
"pending_size": 0,
"open_order": false,
"price": 81909.9,
"ts": 1744267256387,
"side": 1,
"order_type": 1,
"ts_modified": 1744267256390,
"order_status": 1,
"filled_size": 0.001,
"cancelled_size": 0
}
]
| Field | Type | Description |
|---|---|---|
| order_id | long | Order id |
| symbol | string | Contract |
| size / pending_size | decimal | Original and unfilled size |
| open_order | bool | true if open |
| price | decimal | Limit price |
| ts / ts_modified | long | Accepted and last-modified timestamps (ms) |
| side | int | 1 Buy, 2 Sell |
| order_type | int | Order type |
| order_status | int | Order status |
| filled_size / cancelled_size | decimal | Filled and cancelled size |
Trades (Futures)
POST /lp/v1/trades
Request
{
"aid": 1318659424,
"symbol": "BTC_USDT",
"order_id": 0,
"row_count": 1000
}
| Parameter | Type | Required | Description |
|---|---|---|---|
| aid | long | No | Account id |
| symbol | string | Yes | Symbol with an underscore, e.g. BTC_USDT, or ALL |
| order_id | long | No | Return only trades whose order_id >= this value |
| row_count | int | No | 1–1000, default 1000 |
Response
[
{
"trade_id": "b5ab845d-4b6d-4abb-9976-e4c3a2abd552",
"order_id": 5681770932,
"symbol": "BTC-USDT",
"size": 0.001,
"price": 81909.9,
"fee": 0.20477475,
"side": 1,
"ts": 1744267256000
}
]
| Field | Type | Description |
|---|---|---|
| trade_id | string | Trade id |
| order_id | long | Your order id |
| symbol | string | Contract |
| size | decimal | Executed size |
| price | decimal | Execution price |
| fee | decimal | Fee |
| side | int | Your side, 1 Buy, 2 Sell |
| ts | long | Execution timestamp (ms) |
Market data (Futures)
Order book
GET /market/orderbook/{contract}?depth={depth}
| Parameter | Type | Required | Description |
|---|---|---|---|
| contract | string | Yes | e.g. BTC-USDT |
| depth | int | No | Total levels across both sides (split evenly): 5, 10, 20, 50, 100, 500, 1000. Omit it for the full book. |
Response
{
"ts": 1744267256387,
"bids": [[81909.8, 1.2], [81909.5, 0.45]],
"asks": [[81910.0, 0.8], [81910.3, 2.1]]
}
| Field | Type | Description |
|---|---|---|
| ts | long | Server timestamp (ms) |
| bids | array | Buy side, [[price, size], …], best (highest) first |
| asks | array | Sell side, [[price, size], …], best (lowest) first |
Kline (Futures)
GET /market/charts?sym={contract}&ts={ts}&interval={interval}&limit={limit}
| Parameter | Type | Required | Description |
|---|---|---|---|
| sym | string | Yes | Contract, e.g. BTC-USDT |
| ts | long | Yes | End time (ms) |
| interval | int | Yes | 1, 5, 15, 60, 240, 1440, 10080, 43200 |
| limit | int | No | 1–1000, default 250 |
| csv | bool | No | true returns CSV |
Response
[
{
"open": 81826.0,
"high": 81950.5,
"low": 81790.2,
"close": 81902.1,
"volume": 152.384,
"time": 1744272000000
},
{
"open": 81710.4,
"high": 81880.0,
"low": 81655.0,
"close": 81826.0,
"volume": 98.117,
"time": 1744268400000
}
]
| Field | Type | Description |
|---|---|---|
| open | decimal | Opening price |
| high | decimal | Highest price |
| low | decimal | Lowest price |
| close | decimal | Closing price |
| volume | decimal | Volume in base asset |
| time | long | Candle start time (ms) |
Candles are newest first.