AscendEx Pro API Documentation
AscendEx Pro API is the latest release of APIs allowing our users to access the exchange programmatically. It is a major revision of the older releases. The AscendEx team re-implemented the entire backend system in support for the AscendEx Pro API. It is designed to be fast, flexible, stable, and comprehensive.
What's New
- Dynamic subscription/unsubscription to private and public data channels via WebSocket.
- Synchronized/Asynchronized API calls. When placing/cancelling orders, you may use synchronized method to get the order result in a single API call. You may also use asynchronized method to achieve minimum latency.
- Simplified API schemas. For instance, we simplified the cancel order logic, now you can track the entire order
life cycle with only one indentifier (
orderId
). - More detailed error message.
Market Making Incentive Program
AscendEX offers a Market Making Incentive Program for professional liquidity providers. Key benefits of this program include:
- Favorable fee structure.
- Monthly bonus pending satisfying KPI.
- Direct Market Access and Co-location service.
Users with good maker strategies and significant trading volume are welcome to participate in this long-term program. If your account has a trading volume of more than 150,000,000 USDT in the last 30 days on any exchange, please send the following information via email to institution@ascendex.com, with the subject "Market Maker Incentive Application":
- One AscendEX account ID.
- A brief explanation of your market making method (NO detail is needed), as well as estimation of maker orders' percentage.
SDKs and Client Libraries
Official SDK
CCXT is our authorized SDK provider and you may access the AscendEX API through CCXT. For more information, please visit: https://ccxt.trade
Demo Code
We provide comprehensive demos (currently available in python). We provide two types of demo codes:
- Short, self contained demo scripts that you can plugin to you larger system.
- Large, complex demo scripts to show you how to design a trading strategy using APIs from this document.
See https://github.com/ascendex/ascendex-pro-api-demo for more details.
Got Questions?
Join our official telegram channel: https://t.me/AscendEX_Official_API
Release Note
2022-05-19
Limit Info API is deprecated, use Limit Info API v2 to get ban info and message threshold.
2022-02-28
- Added the Limit Info API to get ban info and risk limit info.
2022-02-25
- Update the List all Products API to different endpoints by account type: for cash
/api/pro/v1/cash/products
, for margin/api/pro/v1/margin/products
.
2021-12-02
- Update the Balance Snapshot API and Order and Balance Detail API to different endpoints by account type:
api/pro/data/v1/cash/balance/snapshot
for cash andapi/pro/data/v1/margin/balance/snapshot
for margin balance;api/pro/data/v1/cash/balance/history
for cash andapi/pro/data/v1/margin/balance/history
for margin balance or order fill detail. - Redirect the Order Hist v2 API to new endpoint
api/pro/data/v2/order/hist
(No group in the endpoint anymore), and change prehash string todata/v2/order/hist
. Original way through<group>/api/pro/v2/order/hist
is still supported, but will be removed in the future.
2021-11-22
- Replaced the ticker API
GET api/pro/v1/ticker
withGET api/pro/v1/spot/ticker
to include only spot symbols. The old API will still be available but will be removed in the future. - Added the VIP fee schedule API and the Fee Schedule by Symbol API.
2021-07-16
- Introduced the experimental Balance Snapshot and Order and Balance Detail api.
2021-06-15
- Introduced the List all Assets (version v2) api. The version v1 api will remain available. However, you are highly recommended to upgrade.
2021-06-08
2020-08-10
- We have deprecated list history orders API and replace it with list history orders v2 API.
2020-08-06
- Added
expireTime
andallowedIps
to account info
2020-07-17
- Added API to query deposit addresses.
- Added API to query wallet transaction history
2019-12-26
- Added execution instruction to order messages (place new order, list open/historical orders). This field indicates if the order is Post-Only (
Post
) or forced liquidation (Liquidation
). It is namedexecInst
in RESTful responses andei
in websocket messages.
REST APIs
We always respond with json include code
field to indicate request result. 0
usually means success response, and you could find data in json format in field data
; any code other than 0
indicate failure during the request process. For failure response, usually you could find detailed error in fields message
, reason
, and possibly extra info
.
For private data, such as open order
, balance
, we usually include accountId
, and accountCategory
value in top level of response.
Authenticate a RESTful Request
Create Request
To access private data via RESTful APIs, you must include the following headers:
x-auth-key
- required, the api key as a string.x-auth-timestamp
- required, the UTC timestamp in milliseconds of your requestx-auth-signature
- required, the request signature (see Sign a Request)
The timestamp in the header will be checked against server time. If the difference is greater than 30 seconds, the request will be rejected.
Sign a Request
Signing a RESTful Request
# bash
APIPATH=info
APIKEY=CEcrjGyipqt0OflgdQQSRGdrDXdDUY2x
SECRET=hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk
TIMESTAMP=`date +%s%N | cut -c -13` # 1608133910000
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`
echo $SIGNATURE # /pwaAgWZQ1Xd/J4yZ4ReHSPQxd3ORP/YR8TvAttqqYM=
curl -X GET -i \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "x-auth-key: $APIKEY" \
-H "x-auth-signature: $SIGNATURE" \
-H "x-auth-timestamp: $TIMESTAMP" \
https://ascendex.com/api/pro/v1/info
# python 3.6+
import time, hmac, hashlib, base64
api_path = "info"
api_key = "CEcrjGyipqt0OflgdQQSRGdrDXdDUY2x"
sec_key = "hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk"
timestamp = int(round(time.time() * 1e3)) # 1608133910000
message = bytes(f"{timestamp}+{api_path}", 'utf-8')
secret = bytes(sec_key, 'utf-8')
signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest())
header = {
"x-auth-key": api_key,
"x-auth-signature": signature,
"x-auth-timestamp": timestamp,
}
print(signature) # b'/pwaAgWZQ1Xd/J4yZ4ReHSPQxd3ORP/YR8TvAttqqYM='
// java 1.8+
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class SignatureExample {
public static void main(String[] args) {
try {
long timestamp = System.currentTimeMillis(); // 1562952827927
String api_path = "user/info";
String secret = "hV8FgjyJtpvVeAcMAgzgAFQCN36wmbWuN7o3WPcYcYhFd8qvE43gzFGVsFcCqMNk";
String message = timestamp + "+" + api_path;
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secret_key);
String hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
System.out.println(hash); // vBZf8OQuiTJIVbNpNHGY3zcUsK5gJpwb5lgCgarpxYI=
}
catch (Exception e) {
System.out.println("Error");
}
}
}
To query APIs with private data, you must include a signature using base64 encoded HMAC sha256 algorithm. The prehash string is <timestamp>+<api-path>
.
The timestamp
is the UTC timestamp in milliseconds.
See the code demos in bash
on the right. For other programming languages, please refer to https://github.com/ascendex/ascendex-pro-api-demo/tree/main/signature_demo.
Market Data (Public)
You don't need to sign the request to access public market data.
List all Assets
List all Assets
curl -X GET "https://ascendex.com/api/pro/v2/assets"
Sample Response
{
"code": 0,
"data": [
{
"assetCode": "USDT",
"assetName": "Tether",
"precisionScale": 9,
"nativeScale": 4,
"blockChain": [
{
"chainName": "Omni",
"withdrawFee": "30.0",
"allowDeposit": true,
"allowWithdraw": true,
"minDepositAmt": "0.0",
"minWithdrawal": "50.0",
"numConfirmations": 3
},
{
"chainName": "ERC20",
"withdrawFee": "10.0",
"allowDeposit": true,
"allowWithdraw": true,
"minDepositAmt": "0.0",
"minWithdrawal": "20.0",
"numConfirmations": 12
}
]
}
]
}
HTTP Request
GET /api/pro/v2/assets
You can obtain a list of all assets listed on the exchange through this API.
Response Content
Name | Type | Description |
---|---|---|
assetCode |
String |
asset code. e.g. "BTC" |
assetname |
String |
full name of the asset, e.g. "Bitcoin" |
precisionScale |
Int |
scale used in internal position keeping. |
nativeScale |
Int |
scale used in deposit/withdraw transaction from/to chain. |
blockChain |
List |
block chain specific details |
Blockchain specific details
Name | Type | Description |
---|---|---|
chainName |
String |
name of the blockchain |
withdrawFee |
String |
fee charged for each withdrawal request. e.g. "0.01" |
allowDepoist |
Boolean |
allow deposit |
allowWithdraw |
Boolean |
allow withdrawal |
minDepositAmt |
String |
minimum amount required for the deposit request e.g. "0.0" |
minWithdrawalAmt |
String |
minimum amount required for the withdrawal request e.g. "50" |
numConfirmations |
Int |
number of confirmations needed for the exchange to recoganize a deposit |
List all Products
List all Products
curl -X GET "https://ascendex.com/api/pro/v1/cash/products"
curl -X GET "https://ascendex.com/api/pro/v1/margin/products"
Sample Response
{
"code": 0,
"data": [
{
"symbol": "BTC/USDT",
"displayName": "BTC/USDT",
"domain": "USDS",
"tradingStartTime": 1546300800000,
"collapseDecimals": "1,0.1,0.01",
"minQty": "0.000000001",
"maxQty": "1000000000",
"minNotional": "5",
"maxNotional": "400000",
"statusCode": "Normal",
"statusMessage": "",
"tickSize": "0.01",
"useTick": false,
"lotSize": "0.00001",
"useLot": false,
"commissionType": "Quote",
"commissionReserveRate": "0.001",
"qtyScale": 5,
"priceScale": 2,
"notionalScale": 4
},
]
}
HTTP Request
GET /api/pro/v1/{accountCategory}/products
Response Content
You can obtain a list of all products traded on the exchange through this API.
The response contains the following general fields:
Name | Type | Description |
---|---|---|
symbol |
String |
e.g. "ASD/USDT" |
baseAsset |
String |
e.g. "ASD" |
quoteAsset |
String |
e.g. "USDT" |
status |
String |
"Normal" |
The response also contains criteria for new order request.
Name | Type | Description |
---|---|---|
symbol |
String |
Symbol like BTC/USDT |
displayName |
String |
Symbol's display Name |
domain |
String |
Symbol's Tradins Domain USDS / ETH / BTC |
tradingStartTime |
Number |
Trading Start Time |
collapseDecimals |
String |
Trading Start Time |
minQty |
String |
minimum quantity of an order |
maxQty |
String |
minimum quantity of an order |
minNotional |
String |
minimum notional of an order |
maxNotional |
String |
maximum notional of an order |
statusCode |
String |
Symbol's status code |
statusMessage |
String |
Symbol's status message |
tickSize |
String |
tick size of order price |
useTick |
Boolean |
|
lotSize |
String |
lot size of order quantity |
useLot |
Boolean |
|
commissionType |
String |
"Base" , "Quote" , "Received" |
commissionReserveRate |
String |
e.g. "0.001" , see below. |
qtyScale |
Number |
Quantity Scale |
notionalScale |
Number |
Notional Scale |
When placing orders, you should comply with all criteria above. More details can be found in the Order Request Criteria section.
Ticker
Ticker for one trading pair
// curl -X GET 'https://ascendex.com/api/pro/v1/spot/ticker?symbol=ASD/USDT'
{
"code": 0,
"data": {
"symbol": "ASD/USDT",
"open": "0.06777",
"close": "0.06809",
"high": "0.06899",
"low": "0.06708",
"volume": "19823722",
"ask": [
"0.0681",
"43641"
],
"bid": [
"0.0676",
"443"
]
}
}
List of Tickers for one or multiple trading pairs
// curl -X GET "https://ascendex.com/api/pro/v1/spot/ticker?symbol=ASD/USDT,"
{
"code": 0,
"data": [
{
"symbol": "ASD/USDT",
"open": "0.06777",
"close": "0.06809",
"high": "0.06809",
"low": "0.06809",
"volume": "19825870",
"ask": [
"0.0681",
"43641"
],
"bid": [
"0.0676",
"443"
]
}
]
}
HTTP Request
GET api/pro/v1/spot/ticker
You can get summary statistics of one or multiple symbols (spot market) with this API.
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol |
String |
No | you may specify one, multiple, or all symbols of interest. See below. |
This API endpoint accepts one optional string field symbol
:
- If you do not specify
symbol
, the API will responde with tickers of all symbols in a list. - If you set
symbol
to be a single symbol, such asASD/USDT
, the API will respond with the ticker of the target symbol as an object. If you want to wrap the object in a one-element list, append a comma to the symbol, e.g.ASD/USDT,
. - You shall specify
symbol
as a comma separated symbol list, e.g.ASD/USDT,BTC/USDT
. The API will respond with a list of tickers.
Respond Content
The API will respond with a ticker object or a list of ticker objects, depending on how you set the symbol
parameter.
Each ticker object contains the following fields:
Field | Type | Description |
---|---|---|
symbol |
String |
|
open |
String |
the traded price 24 hour ago |
close |
String |
the last traded price |
high |
String |
the highest price over the past 24 hours |
low |
String |
the lowest price over the past 24 hours |
volume |
String |
the total traded volume in quote asset over the paste 24 hours |
ask |
[String, String] |
the price and size at the current best ask level |
bid |
[String, String] |
the price and size at the current best bid level |
Code Sample
Please refer to python code to query ticker info.
Bar Info
Request
curl -X GET "https://ascendex.com/api/pro/v1/barhist/info"
Sample response
{
"code": 0,
"data": [
{
"name": "1",
"intervalInMillis": 60000
},
{
"name": "5",
"intervalInMillis": 300000
},
{
"name": "15",
"intervalInMillis": 900000
},
{
"name": "30",
"intervalInMillis": 1800000
},
{
"name": "60",
"intervalInMillis": 3600000
},
{
"name": "120",
"intervalInMillis": 7200000
},
{
"name": "240",
"intervalInMillis": 14400000
},
{
"name": "360",
"intervalInMillis": 21600000
},
{
"name": "720",
"intervalInMillis": 43200000
},
{
"name": "1d",
"intervalInMillis": 86400000
},
{
"name": "1w",
"intervalInMillis": 604800000
},
{
"name": "1m",
"intervalInMillis": 2592000000
}
]
}
HTTP Request
GET /api/pro/v1/barhist/info
This API returns a list of all bar intervals supported by the server.
Request Parameters
This API endpoint does not take any parameters.
Resposne
Name | Type | Description |
---|---|---|
name |
String |
name of the interval |
intervalInMillis |
Long |
length of the interval |
Plesae note that the one-month bar (1m
) always resets at the month start. The intervalInMillis
value for the one-month bar
is only indicative.
The value in the name
field should be your input to the Historical Bar Data API.
Historical Bar Data
Request
curl -X GET "https://ascendex.com/api/pro/v1/barhist?symbol=ASD/USDT&interval=1"
Sample response
{
"code": 0,
"data": [
{
"data": {
"c": "0.05019",
"h": "0.05019",
"i": "1",
"l": "0.05019",
"o": "0.05019",
"ts": 1575409260000,
"v": "1612"},
"m": "bar",
"s": "ASD/USDT"},
{
"data": {
"c": "0.05019",
"h": "0.05027",
"i": "1",
"l": "0.05017",
"o": "0.05017",
"ts": 1575409200000,
"v": "57242"
},
"m": "bar",
"s": "ASD/USDT"},
]
}
HTTP Request
GET /api/pro/v1/barhist
This API returns a list of bars, with each contains the open/close/high/low prices of a symbol for a specific time range.
Request Parameters
Name | Type | Required | Description |
---|---|---|---|
symbol |
String |
Yes | e.g. "ASD/USDT" |
interval |
String |
Yes | a string representing the interval type. |
to |
Long |
No | UTC timestamp in milliseconds. If not provided, this field will be set to the current time. |
from |
Long |
No | UTC timestamp in milliseconds. |
n |
Int |
No | default 10, number of bars to be returned, this number will be capped at 500 |
The requested time range is determined by three parameters - to
, from
, and n
- according to rules below:
from
/to
each specifies the start timestamp of the first/last bar.to
is always honored. If not provided, this field will be set to the current system time.- For
from
andto
:- if only
from
is provided, then the request range is determined by[from, to]
, inclusive. However, if the range is too wide, the server will increasefrom
so the number of bars in the response won't exceed 500. - if only
n
is provided, then the server will return the most recentn
data bars to timeto
. However, ifn
is greater than 500, only 500 bars will be returned. - if both
from
andn
are specified, the server will pick one that returns fewer bars.
- if only
Response
Name | Type | value | Description |
---|---|---|---|
m |
String | bar |
message type |
s |
String | symbol | |
data:ts |
Long | bar start time in milliseconds | |
i |
String | interval | |
o |
String | open price | |
c |
String | close price | |
h |
String | high price | |
l |
String | low price | |
v |
String | volume in quote asset |
Code Sample
Please refer python code to [get bar history]{https://github.com/ascendex/ascendex-pro-api-demo/blob/master/python/query_pub_barhist.py}
Order Book (Depth)
Request for Order Book (Depth) Data
curl -X GET "https://ascendex.com/api/pro/v1/depth?symbol=ASD/USDT"
Order Book (Depth) Data - Sample response
{
"code": 0,
"data": {
"m": "depth-snapshot",
"symbol": "ASD/USDT",
"data": {
"seqnum": 5068757,
"ts": 1573165838976,
"asks": [
[
"0.06848",
"4084.2"
],
[
"0.0696",
"15890.6"
]
],
"bids": [
[
"0.06703",
"13500"
],
[
"0.06615",
"24036.9"
]
]
}
}
}
HTTP Request
GET /api/pro/v1/depth
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol |
String | Yes | Valid symbol supported by exchange |
Response Content
data
field in response contains depth data and meta info.
Name | Type | Description |
---|---|---|
m |
String |
"depth-snapshot" |
symbol |
String |
e.g. "ASD/USDT" |
data |
Json |
actual bid and ask info. See below for detail. |
Actual depth data in data
section:
Name | Type | Description |
---|---|---|
seqnum |
Long |
a sequence number that is guaranteed to increase for each symbol. |
ts |
Long |
UTC timestamp in milliseconds when the message is generated by the server |
asks |
[String, String] |
pair of price and size of ask levels |
bids |
[String, String] |
pair of price and size of bid levels |
Demo Sample
Pleas refer to python code to take depth snapshot
Market Trades
Request
curl -X GET "https://ascendex.com/api/pro/v1/trades?symbol=ASD/USDT"
Sample response
{
"code": 0,
"data": {
"m": "trades",
"symbol": "ASD/USDT",
"data": [
{
"seqnum": 144115191800016553,
"p": "0.06762",
"q": "400",
"ts": 1573165890854,
"bm": false // is buyer maker?
},
{
"seqnum": 144115191800070421,
"p": "0.06797",
"q": "341",
"ts": 1573166037845,
"bm": true
}
]
}
}
HTTP Request
GET /api/pro/v1/trades
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol |
String | Yes | Valid symbol supported by exchange | |
n |
Int | No | any positive integer, capped at 100 | number of trades to return. |
Response Content
data
field in response contains trade data and meta info.
Name | Type | Description
m
| String
| trades
symbol
| String
| trade symbol
data
| Json
| A list of trade record; see below for detail.
Trade record information in data
:
Name | Type | Description |
---|---|---|
seqnum |
Long |
the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive |
p |
String |
trade price in string format |
q |
String |
trade size in string format |
ts |
Long |
UTC timestamp in milliseconds |
bm |
Boolean |
If true, the maker of the trade is the buyer. |
Code Sample
Please refer to python code to [query trades]{https://github.com/ascendex/ascendex-pro-api-demo/blob/master/python/query_pub_trades.py}
Account
Account Info
Account Info - Sample response:
{
"code": 0,
"data": {
"accountGroup": 0,
"email": "yyzzxxz@gmail.com",
"expireTime": 1604620800000, // expire time, UTC timestamp in milliseconds. If -1, the api key will not expire
"allowedIps": ["123.123.123.123"],
"cashAccount": [
"dadFNEYEJIJ93CRxdafd3LTCIDIJPCFNIX"
],
"marginAccount": [
"mar2z3CMIEQx4UadasbtQ9JcxWJYgHmcb"
],
"userUID": "U0866943712",
"tradePermission": True,
"transferPermission": True,
"viewPermission": True
}
}
HTTP Request
GET /api/pro/v1/info
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
prehash string
<timestamp>+info
Obtain the account information.
You can obtain your accountGroup
from this API, which you will need to include in the URL for all your private RESTful requests.
Response Content
Name | Type | Description |
---|---|---|
accountGroup |
Int |
non-negative integer |
email |
String |
|
expireTime |
Long |
the time when the API key will be expired (UTC timestamp in milliseconds). If -1, the api key will not expire |
allowedIps |
List[String] |
list of IPs allowed for the api key |
cashAccount |
List[String] |
|
marginAccount |
List[String] |
|
tradePermission |
Boolean |
|
transferPermission |
Boolean |
|
viewPermission |
Boolean |
|
userUID |
String |
an unique id associated with user |
See a demo at query private account info.
VIP Fee Schedule
Fee Schedule - Sample response for general info::
{
"code": 0,
"data":
{
"domain": "spot",
"userUID": "U0866943712",
"vipLevel": 0,
"genericFee":
{
"largeCap":
{
"maker": "0.00085",
"taker": "0.00085"
},
"smallCap":
{
"maker": "0.001",
"taker": "0.001"
}
}
}
}
HTTP Request
GET <account-group>/api/pro/v1/spot/fee/info
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
prehash string
<timestamp>+fee
See a demo at query fee.
Fee Schedule by Symbol
Fee Schedule - Sample response for each symbol::
{
"code": 0,
"data":
{
"domain": "spot",
"userUID": "U0866943712",
"vipLevel": 0,
"productFee":
[
{
"fee":
{
"maker": "0.0001",
"taker": "0.0001"
},
"symbol": "ZEC/BTC"
},
{
"fee":
{
"maker": "0.0001",
"taker": "0.0001"
},
"symbol": "ETC/USDT"
},
{
"fee":
{
"maker": "0.002",
"taker": "0.002"
},
"symbol": "ONG/USDT"
},
{
"fee":
{
"maker": "0.002",
"taker": "0.002"
},
"symbol": "IBVOL/USDT"
}
]
}
}
HTTP Request
GET <account-group>/api/pro/v1/spot/fee
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
prehash string
<timestamp>+fee
See a demo at query fee.
Risk Limit Info(Deprecated)
This API has been deprecated, please use risk limit info v2 instead.
Risk Limit Info
curl -X GET https://ascendex.com/api/pro/v1/risk-limit-info"
Risk Limit Info - Sample response::
{
"code": 0,
"data": {
"ip": "0.0.0.0",
"webSocket": {
"windowSizeInMinutes": 5,
"maxNumRequests": 45,
"maxSessionPerIp": 30,
"isBanned": true,
"bannedUntil": 1644807691158,
"violationCode": 100014,
"reason": "exceeds MAX_REQ_COUNT_PER_IP[45], 49 requests recently"
}
}
}
HTTP Request
GET /api/pro/v1/risk-limit-info
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
ip | String | No | valid ip address | the client's ip address to be checked if it is banned due to violation of risk limits. |
Risk Limit Info (v2)
Risk Limit Info v2
Our message thresholds in web socket are based on op
field and action
field. Each threshold will have two levels, which are based on counts of messages received in 1
minute. If level 1 threshold is violated, this type of messages will be ignored in the following 15 minutes, other functions are not affected. If you keep sending these messages and triggered level 2 threshold, the violated WebSocket session will be killed and this ip will be banned for 15 minutes. Currently, We have following threshold groups:
admin op
, includesauth/ping/pong
stream op
, includessub/unsub
req op
, includes allreq
op, butorder req
andsnapshot req
have their own thresholdsorder req
, includesplace_order/cancel_order/cancel_all
snapshot req
, includesdepth_snapshot/depth_snapshot_top100
All the operations fall into same op
/req
group will share a threshold, meaning the sum of count of these messages should not violate the threshold.
For req op
, we have two fine granularity threshold order req
and snapshot req
, which will have their specialized threshold value for messages belonging to their types.
curl -X GET https://ascendex.com/api/pro/v2/risk-limit-info"
Risk Limit Info - Sample response::
{
"code": 0,
"data": {
"ip": "173.123.133.23",
"webSocket": {
"status": {
"isBanned": false,
"bannedUntil": -1,
"violationCode": 0,
"reason": ""
},
"limits": {
"maxWebSocketSessionsPerIpAccountGroup": 20,
"maxWebSocketSessionsPerIpTotal": 300
},
"messageThreshold": {
"level1OpThreshold": {
"auth": 800,
"ping": 800,
"pong": 800,
"sub": 150,
"unsub": 150,
"req": 10000
},
"level2OpThreshold": {
"auth": 1000,
"ping": 1000,
"pong": 1000,
"sub": 200,
"unsub": 200,
"req": 10000
},
"level1ReqThreshold": {
"place_order": 8000,
"cancel_order": 8000,
"cancel_all": 8000,
"batch_place_order": 10000,
"batch_cancel_order": 10000,
"depth_snapshot": 400,
"depth_snapshot_top100": 400,
"market_trades": 10000,
"balance": 10000,
"open_order": 10000,
"margin_risk": 10000,
"futures_account_snapshot": 10000,
"futures_open_orders": 10000
},
"level2ReqThreshold": {
"place_order": 10000,
"cancel_order": 10000,
"cancel_all": 10000,
"batch_place_order": 10000,
"batch_cancel_order": 10000,
"depth_snapshot": 500,
"depth_snapshot_top100": 500,
"market_trades": 10000,
"balance": 10000,
"open_order": 10000,
"margin_risk": 10000,
"futures_account_snapshot": 10000,
"futures_open_orders": 10000
}
}
}
}
}
HTTP Request
GET /api/pro/v2/risk-limit-info
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
ip | String | No | valid ip address | the client's ip address to be checked if it is banned due to violation of risk limits. |
Exchange Latency Info
Latency Info
curl -X GET https://ascendex.com/api/pro/v1/exchange-info?requestTime="$(date +%s%N | cut -b1-13)"
Latency Info - Sample response::
{
"code": 0,
"data":
{
"requestTimeEcho": 1640052379050,
"requestReceiveAt": 1640052379063,
"latency": 13
}
}
HTTP Request
GET /api/pro/v1/exchange-info
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
requestTime | Long | Yes | milliseconds since UNIX epoch in UTC | the client's local time. The server compare it with the system time to calculate latency. |
Balance
Cash Account Balance
Cash Account Balance - Sample response
{
"code": 0,
"data": [
{
"asset": "USDT",
"totalBalance": "1285.366663467",
"availableBalance": "1285.366663467"
},
{
"asset": "BTC",
"totalBalance": "22.1308675",
"availableBalance": "16.1308675"
},
{
"asset": "ETH",
"totalBalance": "0.6",
"availableBalance": "0.6"
}
]
}
HTTP Request
GET <account-group>/api/pro/v1/cash/balance
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+balance
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
asset | String |
No | valid asset code | this allow you query single asset balance, e.g. BTC |
showAll | Boolean |
No | true / false | by default, the API will only respond with assets with non-zero balances. Set showAll=true to include all assets in the response. |
Response Content
Name | Type | Description | Sample Response |
---|---|---|---|
asset | String |
asset code | "USDT" |
totalBalance | String |
total balance in string format | "1234.56" |
availableBalance | String |
available balance in string format | "234.56" |
Code Sample
Please refer to python code to query balance
Margin Account Balance
Margin Account Balance - Sample response
{
"code": 0,
"data": [
{
"asset": "USDT",
"totalBalance": "11200",
"availableBalance": "11200",
"borrowed": "0",
"interest": "0"
},
{
"asset": "ETH",
"totalBalance": "20",
"availableBalance": "20",
"borrowed": "0",
"interest": "0"
}
]
}
HTTP Request
GET <account-group>/api/pro/v1/margin/balance
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+balance
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
asset | String |
No | valid asset code | this allow you query single asset balance, e.g. BTC |
showAll | Boolean |
No | true / false | by default, the API will only respond with assets with non-zero balances. Set showAll=true to include all assets in the response. |
Response Content
Name | Type | Description | Sample Response |
---|---|---|---|
asset | String |
asset code | "USDT" |
totalBalance | String |
total balance | "1234.56" |
availableBalance | String |
available balance | "234.56" |
borrowed | String |
borrowed amount | "0" |
interest | String |
interest owed | "0" |
Margin Risk Profile
Margin Account Risk Profile - Sample response
{
"code": 0,
"data": {
"accountMaxLeverage": "10",
"availableBalanceInUSDT": "17715.8175",
"totalBalanceInUSDT": "17715.8175",
"totalBorrowedInUSDT": "0",
"totalInterestInUSDT": "0",
"netBalanceInUSDT": "17715.8175",
"pointsBalance": "0",
"currentLeverage": "1",
"cushion": "-1"
}
}
HTTP Request
POST <account-group>/api/pro/v1/margin/risk
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+margin/risk
Code Sample
Please refer to python code to[query margin risk]{https://github.com/ascendex/ascendex-pro-api-demo/blob/master/python/query_prv_margin_risk.py}
Balance Transfer
Transfer from Cash To Margin - Sample request and response
Request
{
"amount": "11.0",
"asset": "USDT",
"fromAccount": "cash",
"toAccount": "margin"
}
Response
{
"code": 0,
}
This api allows balance transfer between different accounts of the same user.
HTTP Request
POST <account-group>/api/pro/v1/transfer
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+transfer
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
amount | String |
Yes | Positive numerical string | Asset amount to transfer. |
asset | String |
Yes | Valid asset code | |
fromAccount | String |
Yes | cash /margin /futures |
|
toAccount | String |
Yes | cash /margin /futures |
Response Content
Response code
value 0 indicate successful transfer.
Code Sample
Please refer to python code to transfer token among different accounts
Balance Transfer for Subaccount
Request
{
"userFrom": "parent-account-userId", // support userId or username, pls use "parentUser" for parent account username
"userTo": "sub-account-userId", // support userId or username, pls use "parentUser" for parent account username
"acFrom": "cash",
"acTo": "cash",
"asset": "USDT",
"amount": "40",
"mode": "ack" // ack/accept. use accept to hold and wait ack from OMS
}
Response
{
"code":0,
"info":{
"acFrom":"cash",
"acTo":"cash",
"amount":"40.0000",
"asset":"USDT",
"userFrom":"parent-account-userId",
"userTo":"sub-account-userId"
}
}
This api allows balance transfer between the parent and sub accounts and between two sub accounts. You can only call this API from the parent account.
HTTP Request
POST <account-group>/api/pro/v2/subuser/subuser-transfer
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+subuser-transfer
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
amount | String |
Yes | Positive numerical string | Asset amount to transfer. |
asset | String |
Yes | Valid asset code | |
userFrom | String |
Yes | userId or username | use parentUser as parent account username |
userTo | String |
Yes | userId or username | use parentUser as parent account username |
acFrom | String |
Yes | cash /margin /futures |
|
acTo | String |
Yes | cash /margin /futures |
|
mode | String |
No | empty/ack /accept |
use accept to hold-and-wait for confirmation from the exchange backend. |
Response Content
Response code
value 0 indicates successful transfer and info
echos the request parameters.
Code Sample
Please refer to python code to transfer token among different sub users
Balance Transfer history for Subaccount
Request
{
"subUserId": null,
"asset": null,
"startTime": null,
"endTime": null,
"page": 1,
"pageSize": 10
}
Response
{
"code": 0,
"data": {
"page": 1,
"pageSize": 10,
"totalSize": 6,
"limit": 10,
"data": [
{
"time": 1620125922493,
"userFrom": "ParentUser",
"userTo": "sub-account-username",
"acFrom": "futures",
"acTo": "cash",
"asset": "USDT",
"amount": "11",
"status": "SUCCESS"
}
...
]
}
}
This api allows to fetch balance transfer history among different sub users based on given filtering conditions. You can only call this API from the parent account.
HTTP Request
POST <account-group>/api/pro/v2/subuser/subuser-transfer-hist
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+subuser-transfer-hist
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
asset | String |
No | Valid asset code | asset to query |
subUserId | String |
No | userId | user id to query |
startTime | Long |
No | timestamp in milliseconds | start time to query |
endTime | Long |
No | timestamp in milliseconds | end time to query |
page | Int |
Yes | number of page | number of page |
pageSize | Int |
Yes | 1-10 | record size in one page |
Response Content
Response code
value 0 indicates successful query and data
shows query result.
Code Sample
Please refer to python code to transfer history among different sub users
Balance Snapshot And Update Detail
Here we provide rest API to get daily balance snapshot, and intraday balance and order fills update details. We recommend calling balance snapshot endpoint(<cash/margin>/balance/snapshot
) to get balance at the beginning of the day, and get the sequence number sn
; then start to query balance or order fills update from <cash/margin>/balance/history
by setting parameter sn
value to be sn + 1
.
Please note we enforce rate limit 8 / minute. Data query for most recent 7 days is supported.
Balance Snapshot
This API returns cash or margin balance snapshot infomation on daily basis.
HTTP Request
For cash
GET api/pro/data/v1/cash/balance/snapshot
For margin
GET api/pro/data/v1/margin/balance/snapshot
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
For cash
<timestamp>+data/v1/cash/balance/snapshot
For margin
<timestamp>+data/v1/margin/balance/snapshot
Cash Account Balance Snapshot - Sample response
{
"meta": {
"ac": "cash",
"accountId": "cshfi7p9j312936d2hkjJpAahWyb4RCJ",
"sn": 10870097597,
"snapshotTime": 1617148800000
},
"snapshot": [
{"asset": "AKRO", "totalBalance": "1858"},
{"asset": "ALTBEAR", "totalBalance": "250"},
{"asset": "ANKR", "totalBalance": "200"}
]
}
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
date | String |
Yes | YYYY-mm-dd |
balance date |
Response Content
Name | Type | Description |
---|---|---|
meta | Json |
meta info. See detail below |
balance | Json Array |
balance info. See detail below |
meta
field provides some basic info.
meta
schema
Name | Type | Description | Sample Response |
---|---|---|---|
ac | String |
account category | "cash" or "margin" |
accountId | String |
accountId | |
sn | Long |
sequence number | |
balanceTime | Long |
balance snapshot time in milli seconds |
balance
field provides asset balance snapshot info.
balance
schema
Name | Type | Description | Sample Response |
---|---|---|---|
asset | String |
asset code | "USDT" |
totalBalance | String |
current asset total balance | "1234.56" |
Code Sample
Please refer to python code to query balance snapshot
Order and Balance Detail
This API is for intraday balance change detail from balance event and order fillss.
HTTP Request
For cash
GET api/pro/data/v1/cash/balance/history
For margin
GET api/pro/data/v1/margin/balance/history
Prehash String
For cash
<timestamp>+data/v1/cash/balance/history
For margin
<timestamp>+data/v1/margin/balance/history
Cash Account Balance Detail - Sample response
{
"meta": {
"ac": "cash",
"accountId": "MPXFNEYEKFK93CREYX3LTCIDIJPCFNIX"
},
"order": [
{
"data": [
{
"asset": "BTC",
"curBalance": "0.0301",
"dataType": "trade",
"deltaQty": "0.0001"
},
{
"asset": "USDT",
"curBalance": "-1628.51466633",
"dataType": "trade",
"deltaQty": "-5.4175"
},
{
"asset": "USDT",
"curBalance": "-1628.51466633",
"dataType": "fee",
"deltaQty": "-0.00270875"
}
],
"liquidityInd": "RemovedLiquidity",
"orderId": "r17873f13ab2U7684538613bbtcpuHLA",
"orderType": "Limit",
"side": "Buy",
"sn": 16823297563,
"transactTime": 1616852892564
}
],
"balance": [
{
"data": [
{
"asset": "BTMX-S",
"curBalance": "40000.112249285",
"deltaQty": "0.000000007"
}
],
"eventType": "Btmxmining",
"sn": 10888843672,
"transactTime": 1617213942176
},
{
"data": [
{
"asset": "BTMX-S",
"curBalance": "40000.112249159",
"deltaQty": "0.000000029"
}
],
"eventType": "Btmxmining",
"sn": 10870559479,
"transactTime": 1617149141108
}
]
}
Wallet
Query Deposit Addresses
Query Deposit Addresses - Sample Response
{
"code": 0,
"data": {
"asset": "USDT",
"assetName": "Tether",
"address": [{
"address": "1P67...TnG3",
"blockchain": "Omni",
"destTag": ""
},
{
"address": "0xd3...c466",
"blockchain": "ERC20",
"destTag": ""
},
{
"address": "TPpK...ovJk",
"blockchain": "TRC20",
"destTag": ""
}
]
}
}
HTTP Request
GET /api/pro/v1/wallet/deposit/address
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+wallet/deposit/address
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
asset | String |
Yes | valid asset code | this allow you query single asset balance, e.g. BTC |
blockchain | Boolean |
No | blockchain name | the (optional) blockchain filter |
Response Content
Name | Type | Description | Sample Response |
---|---|---|---|
asset | String |
asset code | "USDT" |
assetName | String |
asset name | "Tether" |
address | List |
list of address objects |
Content of elements in the address
field:
Name | Type | Description | Sample Response |
---|---|---|---|
address | String |
wallet address | |
blockchain | String |
blockchain name | "ERC20" |
destTag | String |
the destination tag (or memo for some tokens) attached to the address. This field could be an empty string. |
Code Sample
Please refer to python code to query deposit addresses
Wallet Withdrawal
We do support API withdrawals. Please contact your dedicated sales manager or support@ascendex.com for further information.
Query Wallet Transaction History
Query Wallet Transaction History - Sample Response
{
"code": 0,
"data": {
"data": [{
"asset": "USDT",
"amount": "400",
"commission": "0",
"destAddress": {
"address": "1wX8...iHih"
},
"networkTransactionId": "Slc8...xo2d",
"numConfirmations": 3,
"numConfirmed": 0,
"requestId": "ZgO7...cctn",
"status": "confirmed",
"time": 1595001735000,
"transactionType": "withdrawal"
}
],
"hasNext": true,
"page": 1,
"pageSize": 2
}
}
HTTP Request
GET /api/pro/v1/wallet/transactions
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+wallet/transactions
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
asset | String |
No | valid asset code | this allow you query single asset balance, e.g. BTC |
txType | String |
No | deposit / withdrawal |
add the (optional) transaction type filter |
page | Int |
No | a positive interger | the page number, starting at 1 |
pageSize | Int |
No | 1-50, default 20 | the page size, must be positive |
Response Content
Name | Type | Description | Sample Response |
---|---|---|---|
asset | String |
asset code | "USDT" |
amount | String |
the transaction amount | "400" |
commission | String |
the commission charged by the exchange | "0" |
destAddress | Object |
the destination address, see below for details | |
networkTransactionId | String |
the transaction hash ID | |
numConfirmations | Int |
the minimun number of confirmations for the transaction to be viewed as confirmed. | |
numConfirmed | Int |
current number of confirmations | |
requestId | String |
the requestId of the request | |
status | String |
pending / reviewing / confirmed / rejected / canceled / failed |
|
time | Long |
UTC timestamp in milliseconds, timestamp of the transaction. | |
transactionType | String |
deposit / withdrawal |
Content of elements in the destAddress
field:
Name | Type | Description |
---|---|---|
address | String |
wallet address |
destTag | Optional[String] |
the destination tag (or memo for some tokens) attached to the address. This field could be an empty string. |
Code Sample
Please refer to python code to query wallet transactions
Order
Trading and Order related APIs. API path usually depend on account-group and account-category:
account-group : get your account-group from 'Account Info' API
account-category: cash or margin
For all order related ack or data, there is orderId field to identify the order.
Generate Order Id
We use the following method to generate an unique id for each order place/cancel request. (You could get userUID
from Account Info
API.)
Method
A = 'a' for order via rest api, or 's' for order via websocket;
B = Convert timestamp (in miliseconds) to hex string;
C = User UID (11 chars, starting with 'U' followed by 10 digits);
D = If user provide client order Id (with length >= 9, letters and digits only), then take the right 9 chars; otherwise, we randomly generate 9 chars;
Final order Id is concatenation of strings A, B, C, D from above steps, i.e., orderId = A + B + C + D.
Extra info on id
id
value must satisfy regrex pattern"^\w[\w\-]*\w$"
(i.e. start and end with word character), and with length up to 32. ("Invalid Client Order id" error for violation)id
value with length 9 is recommended, since we take the right most 9 chars for order Id generation.id
value with length < 9 will not be used in order Id generation, but we still echo it back in order ack message (empty string when noid
value provided).If a valid
id
value is provided when placing order, order Id from server side is pre-determined. This could be helpful for order status check in case of accidently internet connection issue.
Code Sample
Please refer to python code to gen server order id
Place Order
Place Order - Successful ACK Response (Status 200, code 0)
{
"code": 0,
"data": {
"ac": "MARGIN",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "place-order",
"info": {
"id": "16e607e2b83a8bXHbAwwoqDo55c166fa",
"orderId": "16e85b4d9b9a8bXHbAwwoqDoc3d66830",
"orderType": "Market",
"symbol": "BTC/USDT",
"timestamp": 1573576916201
},
"status": "Ack"
}
}
Place Order with
ACCEPT
respInst
{
"id": "iGwzbzWxxcHwno4b8VCvh8aaYCJaPALm",
"time": 1575403713964,
"symbol": "BTC/USDT",
"orderPrice": "7289.0",
"orderQty": "0.00082",
"orderType": "limit",
"side": "sell",
"respInst": "ACCEPT"
}
Successful ACCEPT Response (Status 200, code 0)
{
"code": 0,
"data": {
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "place-order",
"info": {
"avgPx": "0",
"cumFee": "0",
"cumFilledQty": "0",
"errorCode": "",
"feeAsset": "USDT",
"lastExecTime": 1575573998500,
"orderId": "a16ed787462fU9490877774N4KBHIVN0",
"orderQty": "0.00081",
"orderType": "Limit",
"price": "7019",
"seqNum": 2323407894,
"side": "Buy",
"status": "New",
"stopPrice": "",
"symbol": "BTC/USDT",
"execInst": "NULL_VAL"
},
"status": "ACCEPT"
}
}
Place Order with
DONE
respInst
{
"id": "UHTe3uVB0KhNGatoRS10YgABwHW0fCYn",
"time": 1575348906131,
"symbol": "BTC/USDT",
"orderQty": "0.00082",
"orderType": "market",
"side": "buy",
"respInst": "DONE"
}
Successful DONE Response (Status 200, code 0)
{"code": 0,
"data": {
"ac": "CASH",
"accountId": "MPXFNEYEJIJ93CREXT3LTCIDIJPCFNIX",
"action": "place-order",
"info": {
"avgPx": "7399.99",
"cumFee": "0.003296696",
"cumFilledQty": "0.00081",
"errorCode": "",
"feeAsset": "USDT",
"id": "ROunD0hpprO2KEgkVK30FOIpPK3zuGGh",
"lastExecTime": 1575646514077,
"orderId": "a16edbd9aefaU9490877774pPK3zuGGh",
"orderQty": "0.00081",
"orderType": "Market",
"price": "",
"seqNum": 2348421435,
"side": "Sell",
"status": "Filled",
"stopPrice": "",
"symbol": "BTC/USDT",
"execInst": "NULL_VAL"
},
"status": "DONE"}}
Place Order - Error Response (Status 200, code 300011)
{
"code": 300011,
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "place-order",
"info": {
"id": "JkpnjJRuBtFpW7F7PWDB7uwBEJtUOISZ",
"symbol": "BTC/USDT"
},
"message": "Not Enough Account Balance",
"reason": "INVALID_BALANCE",
"status": "Err"
}
Place a new order.
HTTP Request
POST <account-group>/api/pro/v1/{account-category}/order
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol | String | Yes | ||
time | Long | Yes | milliseconds since UNIX epoch in UTC | We do not process request placed more than 30 seconds ago. |
orderQty | String | Yes | Order size. Please set scale properly for each symbol. | |
orderType | String | Yes | ["market", "limit", "stop_market", "stop_limit"] | Order type |
side | String | Yes | ["buy", "sell"] | |
id | String | No | >=9 chars(letter and digit number only) | Optional but recommended. We echo it back to help you match response with request. |
orderPrice | String | No | The limit price for limit order. Please set price scale properly. | |
stopPrice | String | No | Trigger price of stop limit order | |
postOnly | Boolean | No | [true, false] | |
timeInForce | String | No | ["GTC", "IOC", "FOK"] | GTC: good-till-canceled; IOC: immediate-or-cancel; FOK: fill-or-kill. GTC by default. |
respInst | String | No | ["ACK", "ACCEPT", "DONE"] | Response instruction. Refer to "Response" below. "ACK" by default. |
The table below shows how to correctly configure order of different types: (o - required, x - optional)
Name | market | limit | stop_market | stop_limit |
---|---|---|---|---|
id | x | x | x | x |
time | o | o | o | o |
symbol | o | o | o | o |
orderPrice | o | o | ||
orderQty | o | o | o | o |
orderType | o | o | o | o |
side | o | o | o | o |
postOnly | x | |||
stopPrice | o | o | ||
timeInForce | x |
Order Request Criteria
When placing a new limit order, the request parameters must meet all criteria defined in the Products API:
- The order notional must be within range
[minNotional, maxNotional]
. For limit orders, the order notional is defined as the product oforderPrice
andorderQty
. orderPrice
andstopPrice
must be multiples oftickSize
.orderQty
must be a multiple oflotSize
.- If you are trading using the margin account,
marginTradable
must betrue
. - For cash trading, you must have sufficient balance to fund the order.
- for buy orders, if
commissionType=Quote
, the quote asset balance must be no less thanorderPrice * orderQty * (1 + commissionReserveRate)
. For all othercommissionType
s (Base
andReceived
), the quote asset balance must be no less thanorderPrice * orderQty
- for sell orders, if
commissionType=Base
, your base asset balance must be no less thanorderQty * (1 + commissionReserveRate)
, For othercommissionType
s (Received
andQuote
), the base asset balance must be no less thanorderQty
.
- for buy orders, if
- For margin trading, you must make sure you have sufficient max sellable amount to fund the order.
Response
In "Err" response, id is the id provided by user when placing order; for other responses, orderId is the id generated by server following "Order id generation method" above, and this is the id you should provide for future order query or cancel.
In case you want to cancel an order before response from server, you could figure out the orderId following Order id generation method above.
ACK
Response with 0 code
and status Ack
to indicate new order request received by our server and passed some basic order field check. This is the default response type. If awaiting async order (ACCEPT or DONE) numbers exceeds capacity 1000, then the rest async order will be ACK automatically.
data
schema:
Name | Type | Description |
---|---|---|
avgPx |
String |
average fill price |
cumFee |
String |
cumulated filled comission |
cumFilledQty |
String |
cumulated filled qty |
errorCode |
String |
Could be empty (see detail below) |
feeAsset |
String |
Fee asset, e.g, USDT |
id |
String |
id from request |
lastExecTime |
String |
latest execution timestamp |
orderId |
String |
order id, this is what you should provide for future order query or cancel. |
orderQty |
String |
order quantity |
orderType |
String |
order type |
price |
String |
order price |
seqNum |
Long |
sequence number |
side |
String |
order side |
status |
String |
order status |
stopPrice |
String |
stop price(could be empty) |
symbol |
String |
symbol |
execInst |
String |
execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise. |
errorCode
Field
Value | Description |
---|---|
NoOpenForCancel | Active order is not found: order does not exist or has been filled/canceled. |
TooLateToCancel | Order has been filled/canceled. |
DupCancelCoid | Order is already in cancel pending status |
ACCEPT
Response with 0 code
and status ACCEPT
to indicate new order request is accepted by our match engine. Return normal 'Ack' response if no 'New' status update within 5 seconds. Order status
in data
could be New
, or PendingNew
.
DONE
Response with 0 code
and status Done
to indicate the order request is partially filled, fully filled, or rejected by matching engine. Return normal 'Ack' response if no order status update within 5 seconds. Order status
in data
could be Filled
, PartiallyFilled
, Canceled
, or Rejected
, and so on.
ERR
Response with code
other than 0 and status Err
to provide detailed error information on the order request.
Name | Type | Description |
---|---|---|
code |
Long |
none 0 to indicate error |
ac |
String |
CASH , MARGIN |
accountId |
String |
account id |
action |
String |
place-order |
message |
String |
detail error message |
reason |
String |
error info code, e.g. "INVALID_ORDER_ID" |
status |
String |
"Err" |
info |
Json |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
symbol |
String |
symbol |
id |
String |
id from request if provided |
Error Response Messages (TODO: verify HTTP Status Code)
HTTP Status Code | Error Code | Reason | Example |
---|---|---|---|
400 | xxx | Parameter Error |
Code Sample
Refer to sample python code to place order
Cancel Order
Cancel Order - Successful ACK Response (Status 200, code 0)
{
"code": 0,
"data": {
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "cancel-order",
"status": "Ack",
"info": {
"id": "wv8QGquoeamhssvQBeHOHGQCGlcBjj23",
"orderId": "16e6198afb4s8bXHbAwwoqDo2ebc19dc",
"orderType": "", // could be empty
"symbol": "ETH/USDT",
"timestamp": 1573594877822
}
}
}
Cancel Order - Error Response (Status 200, code 0)
{
"code": 300006,
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "cancel-order",
"status": "Err",
"message": "Invalid Client Order Id: jHAfoOqZmRv3GP1URJ5624moJ9RCG2@3",
"reason": "INVALID_ORDER_ID",
"info": {
"id": "jHAfoOqZmRv3GP1URJ5624moJ9RCG2@3",
"symbol": "ETH/USDT"
}
}
Cancel an existing open order.
HTTP Request
DELETE <account-group>/api/pro/v1/{account-category}/order
Set account-category
to cash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
id | String | No | 32 chars(letter and digit number only) | We echo it back to help you identify the response if provided. This field is optional |
orderId | String | Yes | 32 chars order id responded by server when place order | You should set the value to be the orderId of the target order you want to cancel. |
symbol | String | Yes | Symbol of the order to cancel | |
time | Long | Yes | milliseconds since UNIX epoch in UTC | We do not process request placed more than 30 seconds ago. |
Response
ACK
Response with status "Ack" to indicate the cancel order request is received by server. And you should use provided "orderId" to check cancel status in the future; we also echo back id from your request for reference purpose.
ERR
Response with status "Err" to indicate there is something wrong with the cancel order request. We echo back the coid field in your request.
Error message
for error code 300019
:
Value | Description |
---|---|
Duplicated order cancel request. |
Trying to cancel the same order again in a short time. |
Trying to cancel non-open order |
Trying to cancel a completed (filled/canceled/rejected) or not existed order. |
Code Sample
Refer to sample python code to cancel order
Cancel All Orders
Cancel All Orders - Successful ACK Response (Status 200, code 0)
{
"code": 0,
"data": {
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "cancel-all",
"info": {
"id": "2bmYvi7lyTrneMzpcJcf2D7Pe9V1P9wy",
"orderId": "",
"orderType": "NULL_VAL",
"symbol": "",
"timestamp": 1574118495462
},
"status": "Ack"
}
}
Cancel all current open orders for the account specified, and optional symbol.
HTTP Request
DELETE <account-group>/api/pro/v1/{account-category}/order/all
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/all
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol | String | No | Valid symbol supported by exchange | If provided, only cancel all orders on this symbol; otherwise, cancel all open orders under this account. |
Response
Response include code
and data
, and status Ack
(in field data
) to indicate cancel all order request is received by server.
data
schema:
Name | Type | Description |
---|---|---|
ac |
String |
CASH , MARGIN |
accountId |
String |
account Id |
action |
String |
cancel-all , |
info |
Json |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
id |
String |
echo back the id in request |
orderId |
String |
empty |
orderType |
String |
empty |
symbol |
String |
symbol in request |
timestamp |
Long |
server received timestamp |
Code Sample
Refer to sample python code to cancel all order
Caveat
The server will process the cancel all request with best effort. Orders sent but un-acked will not be canceled. You should rely on websocket order update messages or the RESTful api to obtain the latest status of each order.
Place Batch Orders
Place Batch Orders - Request Body
{
"orders": [
{
"id" : "sampleRequestId1",
"time" : 1573596819085,
"symbol" : "BTC/USDT",
"orderPrice": "34000",
"orderQty" : "0.1",
"orderType" : "limit",
"side" : "buy"
},
{
"id" : "sampleRequestId2",
"time" : 1573596819085,
"symbol" : "BTC/USDT",
"orderPrice": "35000",
"orderQty" : "0.2",
"orderType" : "limit",
"side" : "buy"
}
]
}
Place Batch Orders - Successful ACK Response (Status 200, code 0)
{
"code": 0,
"data": {
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "batch-place-order",
"info": [
{
"id": "sampleRequestId1",
"orderId": "16e80b75cbda8bXHbAwwoqDoa5be7384",
"orderType": "Limit",
"symbol": "BTC/USDT",
"timestamp": 1573596819185
},
{
"id": "sampleRequestId2",
"orderId": "16e61adeee5a8bXHbAwwoqDo100e364e",
"orderType": "Limit",
"symbol": "BTC/USDT",
"timestamp": 1573596819185
}
],
"status": "Ack"
}
}
Place Batch Orders - Error Response (Status 200, code 0)
{
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "batch-place-order",
"code": 300013,
"info": [
{
"code": 300004,
"id": "nGFdep927xsqSaL2B4R3jDSm1IGwcfmr",
"message": "Notional is too small.",
"reason": "INVALID_NOTIONAL",
"symbol": "BTC/USDT"},
{"code": 300013,
"id": "PGEcSVsoQWythsYTs2hWfogLoRs6hhi8",
"message": "Some invalid order in this batch.",
"reason": "INVALID_BATCH_ORDER",
"symbol": "ETH/USDT"}],
"message": "Batch Order failed, please check each order info for detail.",
"reason": "INVALID_BATCH_ORDER",
"status": "Err"
}
Place multiple orders in a batch. If some order in the batch failed our basic check, then the whole batch request fail.
You may submit up to 10 orders at a time. Server will respond with error if you submit more than 10 orders.
HTTP Request
POST <account-group>/api/pro/v1/{account-category}/order/batch
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/batch
Request Parameters
Name | Data Type | Description |
---|---|---|
orders | List | List of order items |
please refer to placing new order for order item definition.
Response
ACK
0 for code
and status Ack
to indicate the batch order request is accepted by server. Field "info" includes server generated "coid" for each order in the batch request, and this is the id you should use for future status query.
data
schema:
Name | Type | Description |
---|---|---|
ac |
String |
CASH , MARGIN |
accountId |
String |
account Id |
action |
String |
cancel-all |
status |
String |
Ack |
info |
List |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
id |
String |
echo back the id in request |
orderId |
String |
server assigned order Id for this single order |
orderType |
String |
order type |
symbol |
String |
symbol in request |
timestamp |
Long |
server received timestamp |
ERR
Non 0 code
and status ERR
to indicate the batch order request is accepted by server. Field info
includes detailed order information to explain why the batch request fail for each individual order. "coid" is original order id provided by user for each order.
Error schema
Name | Type | Description |
---|---|---|
code |
Long |
0 |
ac |
String |
CASH , MARGIN |
accountId |
String |
account Id |
action |
String |
batch-cancel-order |
message |
String |
error message detail |
reason |
String |
short error message |
status |
String |
Err |
info |
List |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
code |
Long |
0 |
id |
String |
echo id in request |
orderId |
String |
empty |
message |
String |
error message detail |
reason |
String |
short error message |
symbol |
String |
symbol in order |
Code Sample
Please refer to python code to place batch order
Cancel Batch Orders
Cancel Batch Orders - Successful ACK Response (Status 200, code 0)
{
"code": 0,
"data": {
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "batch-cancel-order",
"status": "Ack",
"info": [
{
"id": "0a8bXHbAwwoqDo3b485d7ea0b09c2cd8",
"orderId": "16e61d5ff43s8bXHbAwwoqDo9d817339",
"orderType": "NULL_VAL",
"symbol": "BTC/USDT",
"timestamp": 1573619097746
},
{
"id": "0a8bXHbAwwoqDo7d303e2edf6c26d1be",
"orderId": "16e61adeee5a8bXHbAwwoqDo100e364e",
"orderType": "NULL_VAL",
"symbol": "ETH/USDT",
"timestamp": 1573619098342
}
]
}
}
Cancel Batch Orders - Error Response (Status 200, code 0)
{
"code": 300013,
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"action": "batch-place-order",
"message": "Batch Order failed, please check each order info for detail.",
"reason": "INVALID_BATCH_ORDER",
"status": "Err",
"info": [
{
"code": 300006,
"id": "NUty15oXcNt9JAngZ1D6q6jY15LOpKPC",
"orderId": "16e61d5ff43s8bXHbAwwoqDo9d817339",
"message": "The order is already filled or canceled.",
"reason": "INVALID_ORDER_ID",
"symbol": ""
},
{
"code": 300006,
"id": "mpoL0q8cheL8PL2UstJFRzp6yuPk1sGc",
"orderId": "16e61adeee5a8bXHbAwwoqDo100e364e",
"message": "The order is already filled or canceled.",
"reason": "INVALID_ORDER_ID",
"symbol": ""
}
]
}
Cancel multiple orders in a batch. If some order in the batch failed our basic check, then the whole batch request failed.
HTTP Request
DELETE <account-group>/api/pro/v1/{account-category}/order/batch
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/batch
Response
ACK
Response with code
as 0 to indicate batch is successfuly received by server and pass some basic check. data
field explains order ack detail.
Order detail for each order is in info
field list.
data
schema:
Name | Type | Description |
---|---|---|
ac |
String |
CASH , MARGIN |
accountId |
String |
account Id |
action |
String |
cancel-all |
status |
String |
Ack |
info |
List |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
id |
String |
echo back the id in request |
orderId |
String |
orderId in request to cancel |
orderType |
String |
empty |
symbol |
String |
symbol in request |
timestamp |
Long |
server received timestamp |
ERR
Response with non 0 code
and status "Err" to explain detailed failure reason for each order in the batch request. Error detail for each order is in info
field.
Error schema
Name | Type | Description |
---|---|---|
code |
Long |
0 |
ac |
String |
CASH , MARGIN |
accountId |
String |
account Id |
action |
String |
batch-cancel-order |
message |
String |
error message detail |
reason |
String |
short error message |
status |
String |
Err |
info |
List |
See below for detail |
info
schema:
Name | Type | Description |
---|---|---|
code |
Long |
0 |
id |
String |
echo id in request |
orderId |
String |
orderId in request to cancel |
message |
String |
error message detail |
reason |
String |
short error message |
symbol |
String |
symbol in order |
Code Sample
please refer to python code to cancel batch order
Query Order
Query Order - Successful Response (Status 200, code 0)
{
"code": 0,
"accountCategory": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"data": [
{
"symbol": "BTC/USDT",
"price": "8130.24",
"orderQty": "0.00082",
"orderType": "Limit",
"avgPx": "7391.13",
"cumFee": "0.005151618",
"cumFilledQty": "0.00082",
"errorCode": "",
"feeAsset": "USDT",
"lastExecTime": 1575953134011,
"orderId": "a16eee206d610866943712rPNknIyhH",
"seqNum": 2622058,
"side": "Buy",
"status": "Filled",
"stopPrice": "",
"execInst": "NULL_VAL"
},
{
"symbol": "BTC/USDT",
"price": "8131.22",
"orderQty": "0.00082",
"orderType": "Market",
"avgPx": "7392.02",
"cumFee": "0.005152238",
"cumFilledQty": "0.00082",
"errorCode": "",
"feeAsset": "USDT",
"lastExecTime": 1575953151764,
"orderId": "a16eee20b6750866943712zWEDdAjt3",
"seqNum": 2623469,
"side": "Buy",
"status": "Filled",
"stopPrice": "",
"execInst": "NULL_VAL"
}
]
}
Query order status, either open or history order.
HTTP Request
GET <account-group>/api/pro/v1/{account-category}/order/status?orderId={orderId}
Set account-category
tocash
for cash account and margin
for margin account.
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
orderId |
String |
No | one or more order Ids separated by comma |
orderId
could be a single order Id, or multiple order Ids separated by a comma (,
):
- If you set
symbol
to be a single symbol, such asASD/USDT
, the API will respond with the target order as an object. If you want to wrap the object in a one-element list, append a comma to the symbol, e.g.ASD/USDT,
. - You shall specify
symbol
as a comma separated symbol list, e.g.ASD/USDT,BTC/USDT
. The API will respond with a list of order objects.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/status
Response
Returns a list order information in data
field. Please use orderId
field to match with your order.
Name | Type | Description |
---|---|---|
avgPx |
String |
average fill price |
cumFee |
String |
cumulated filled comission |
cumFilledQty |
String |
cumulated filled qty |
errorCode |
String |
Could be empty |
feeAsset |
String |
Fee asset, e.g, USDT |
lastExecTime |
String |
latest execution timestamp |
orderId |
String |
order id |
orderQty |
String |
order quantity |
orderType |
String |
order type |
price |
String |
order price |
seqNum |
Long |
sequence number |
side |
String |
order side |
status |
String |
order status |
stopPrice |
String |
stop price(could be empty) |
symbol |
String |
symbol |
execInst |
String |
execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise. |
Code Sample
Please refer to python code to get order status
List Open Orders
Open Orders - Successful Response (Status 200, code 0)
{"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"code": 0,
"data": [
{
"avgPx": "0", // Average filled price of the order
"cumFee": "0", // cumulative fee paid for this order
"cumFilledQty": "0", // cumulative filled quantity
"errorCode": "", // error code; could be empty
"feeAsset": "USDT", // fee asset
"lastExecTime": 1576019723550, // The last execution time of the order
"orderId": "s16ef21882ea0866943712034f36d83", // server provided orderId
"orderQty": "0.0083", // order quantity
"orderType": "Limit", // order type
"price": "7105", // order price
"seqNum": 8193258, // sequence number
"side": "Buy", // order side
"status": "New", // order status on matching engine
"stopPrice": "", // only available for stop market and stop limit orders; otherwise empty
"symbol": "BTC/USDT",
"execInst": "NULL_VAL" // execution instruction
},
...
]
}
This API returns all current open orders for the account specified.
HTTP Request
GET <account-group>/api/pro/v1/{account-category}/order/open
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/open
Request Parameters
Name | Type | Required | Value Range | Description |
---|---|---|---|---|
symbol |
String |
No | A valid symbol | add a symbol filter. |
Response
Return a list of order infomation in data
field:
Name | Type | Description |
---|---|---|
avgPx |
String |
average fill price |
cumFee |
String |
cumulated filled comission |
cumFilledQty |
String |
cumulated filled qty |
errorCode |
String |
Could be empty |
feeAsset |
String |
Fee asset, e.g, USDT |
lastExecTime |
String |
latest execution timestamp |
orderId |
String |
order id |
orderQty |
String |
order quantity |
orderType |
String |
order type |
price |
String |
order price |
seqNum |
Long |
sequence number |
side |
String |
order side |
status |
String |
order status |
stopPrice |
String |
stop price(could be empty) |
symbol |
String |
symbol |
execInst |
String |
execution instruction, POST for Post-Only orders, Liquidation for forced-liquidation orders, and NULL_VAL otherwise. |
Error Response Messages
HTTP Status Code | Error Code | Reason | Example |
---|---|---|---|
400 | xxx | Parameter Error | {"code": xxx, "message": "missing requird parameter \"account\"} "} @TODO |
Code Sample
Please refer to python code to get open orders
Change from the previous version:
execId
,asdCommission
,notional
are no longer included in the response.errorCode
is no longer included in the open order response. It is still included in the historical order query response.
List Current History Orders
Current History Orders - Successful Response (Status 200, code 0)
{
"ac": "CASH",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"code": 0,
"data": [
{
"avgPx": "7243.34",
"cumFee": "0.051101764",
"cumFilledQty": "0.0083",
"errorCode": "",
"feeAsset": "USDT",
"lastExecTime": 1576019215402,
"orderId": "s16ef210b1a50866943712bfaf1584b",
"orderQty": "0.0083",
"orderType": "Market",
"price": "7967.62",
"seqNum": 8159713,
"side": "Buy",
"status": "Filled",
"stopPrice": "",
"symbol": "BTC/USDT",
"execInst": "NULL_VAL"
},
...
]
}
This API returns all current history orders for the account specified. If you need earlier data or more filter, please refer to Order History API.
HTTP Request
GET <account-group>/api/pro/v1/{account-category}/order/hist/current
Set account-category
tocash
for cash account and margin
for margin account.
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+order/hist/current
Request Parameters
Name | Type | Required | Description |
---|---|---|---|
n |
Int |
No | maximum number of orders to be included in the response |
symbol |
String |
No | symbol filter, e.g. "ASD/USDT" |
executedOnly |
Boolean |
No | if True , include orders with non-zero filled quantities only. |
Response
Return a list of history orders in "data" field.
Code Sample
Please refer to python code to get recent hist orders
List History Orders (Deprecated)
This API has been deprecated, please use list order history v2 instead.
If you still want to use the already deprecated api, please refer to List History Orders (Deprecated).
List History Orders (v2)
History Orders - Successful Response (Status 200, code 0)
{
"code": 0,
"data": [
{
"orderId" : "a173ad938fc3U22666567717788c3b66", // orderId
"seqNum" : 18777366360, // sequence number
"accountId" : "cshwSjbpPjSwHmxPdz2CPQVU9mnbzPpt", // accountId
"symbol" : "BTC/USDT", // symbol
"orderType" : "Limit", // order type (Limit/Market/StopMarket/StopLimit)
"side" : "Sell", // order side (Buy/Sell)
"price" : "11346.77", // order price
"stopPrice" : "0", // stop price (0 by default)
"orderQty" : "0.01", // order quantity (in base asset)
"status" : "Canceled", // order status (Filled/Canceled/Rejected)
"createTime" : 1596344995793, // order creation time
"lastExecTime": 1596344996053, // last execution time
"avgFillPrice": "11346.77", // average filled price
"fillQty" : "0.01", // filled quantity (in base asset)
"fee" : "-0.004992579", // cummulative fee. if negative, this value is the commission charged; if possitive, this value is the rebate received.
"feeAsset" : "USDT" // fee asset
}
]
}
This API returns history orders according to specified parameters (up to 500 records). You have access to at least 30 days of order history.
HTTP Request
GET api/pro/data/v2/order/hist
Signature
You should sign the message in header as specified in Authenticate a RESTful Request section.
Prehash String
<timestamp>+data/v2/order/hist
Request Parameters
Name | Type | Required | Description |
---|---|---|---|
account |
String |
Yes | account type: cash /margin /futures , or actual accountId |
symbol |
String |
No | symbol filter, e.g. ASD/USDT |
startTime |
Long |
No | start time in milliseconds. |
endTime |
Long |
No | end time in milliseconds. |
seqNum |
Long |
No | the seqNum to search from. All records in the response have seqNum no less than the input argument. |
limit |
Int |
No | number of records to return. default 500, max 1000. |
Please note seqNum
increases regirously but not continuously in response.
Rule for combination usage of startTime
, endTime
, and seqNum
:
- If at least one of
seqNum
andstartTime
is provided, the search will start from the oldest possible record (after givenstartTime
orseqNum
). - If neither
seqNum
norstartTime
is provided, the search will start from the latest record (orendTime
if provided) to the oldest.
To retrieve the full history of orders, it is recommended to use seqNum
and follow the procedure below:
- Query the first batch of orders by sending a query with only
startTime
specifying. - Let
n
be the largestseqNum
of orders obtained from the previous query, query the next batch by only settingseqNum = n+1
. - repeat the previous step until you have reached the latest record.
Response
Return a list of history orders in "data" field.
Name | Type | Description |
---|---|---|
orderId |
String |
order id |
seqNum |
Long |
sequence number |
accountId |
String |
account Id |
symbol |
String |
symbol |
orderType |
String |
order type |
side |
String |
order side |
price |
String |
order price |
stopPrice |
String |
stop price (0 by default) |
orderQty |
String |
order quantity |
status |
String |
order status |
createTime |
Long |
order sending time |
lastExecTime |
String |
latest execution timestamp |
avgFillPrice |
String |
average fill price |
fillQty |
String |
cumulated filled qty |
fee |
String |
cummulative fee. if positive, this value is the commission charged; if negative, this value is the rebate received. |
feeAsset |
String |
Fee asset, e.g, USDT |
Code Sample
Please refer to python code to get hist orders
WebSocket
General Message Request/Handling Logic from Client Side
- Client usually initiate request with
op
parameter (followed by other required parameters). - Server usually reply message with
m
value to indicate message topic, e.g.,order
,depth
,auth
. - Private data response usually has
accountId
field, such asorder
,balance
; public data response usually containssymbol
field. - Uniquie
id
parameter is recommended for your request. We will echo it back for you to track the requests. (The only exception isdepth-snapshot
, we do not includeid
)
WebSocket Request
WSS <account-group>/api/pro/v1/stream
In order to authorize the session you must include <account-group>
in the URL. Without <account-group>
, you can
only subscribe to public data.
Code Sample
Please refer to python code for all kinds of [websocket operation]{https://github.com/ascendex/ascendex-pro-api-demo/blob/master/python/client.py} (e.g. authorization, sub/unsub, place/cancel order, and so on)
Keep the Connection Alive via Ping/Pong
In order to keep the websocket connection alive, you have two options, detailed below.
Method 1: Responding to Server ping messages
Method 1. keep the connection alive by responding to Server pushed ping message
<<< { "m": "ping", "hp": 3 } # Server pushed ping message
>>> { "op": "pong" } # Client responds with pong
If the server doesn't receive any client message after a while, it will send a ping
message to the client. Once the ping
message is received,
the client should promptly send a pong
message to the server. If you missed two consecutive ping
messages, the session will be disconnected.
Server Ping Message Schema
Name | Type | Description |
---|---|---|
op |
String |
ping |
hp |
Int |
health point: when this value decreases to 0, the session will be disconnected. |
Method 2: Sending ping messages to Server
Method 2. keep the connection alive by sending ping message to the server
>>> { "op": "ping" } # Client initiated ping message (every 30 seconds)
<<< { "m":"pong", "code":0, "ts":1574260701259, "hp": 2 } # Server responds to client ping
You can also send ping
message to the server every 15 seconds to keep the connection alive. The server will stop sending ping
message
for 30 seconds if a client initiated ping
message is received.
Server Pong Message Schema
Name | Type | Description |
---|---|---|
m |
String |
pong |
code |
Int |
error code, for the pong mesage, the error code is always 0 (success) |
ts |
Long |
server time in UTC miliseconds |
hp |
Int |
health point: when this value decreases to 0, the session will be disconnected. |
WebSocket Authentication
You must authenticate the websocket session in order to recieve private data and send account specific requests (e.g. placing new orders).
You have two options to authenticate a websocket session.
- by adding authentication data in the request header when connecting to websocket.
- by sending an
op:auth
message to the server after you have connected to websocket.
Once you successfully connect to the websocket, you will receive a connected
message:
- for authenticated websocket session:
{"op":"connected","type":"auth"}
- for unauthenticated websocket session:
{"op":"connected","type":"unauth"}
If the session is disconnected for some reason, you will receive a disconnected
message:
{"m":"disconnected","code":100005,"reason":"INVALID_WS_REQUEST_DATA","info":"Session is disconnected due to missing pong message from the client"}
Method 1 - WebSocket Authentication with Request Headers
Authenticate with Headers
# # Install wscat from Node.js if you haven't
# npm install -g wscat
APIPATH=stream
APIKEY=BclE7dBGbS1AP3VnOuq6s8fJH0fWbH7r
SECRET=fAZcQRUMxj3eX3DreIjFcPiJ9UR3ZTdgIw8mxddvtcDxLoXvdbXJuFQYadUUsF7q
TIMESTAMP=`date +%s%N | cut -c -13`
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`
wscat -H "x-auth-key: $APIKEY" \
-H "x-auth-signature: $SIGNATURE" \
-H "x-auth-timestamp: $TIMESTAMP" \
-c wss://ascendex.com/1/api/pro/v1/stream -w 1 -x '{"op":"sub", "id": "abc123", "ch": "order:cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo:ASD/USDT"}'
This is similar to the way you authenticate any RESTful request. You need to add the following header fields to the connection request:
x-auth-key
x-auth-timestamp
x-auth-signature
The server will then check if the data is correctly signed before upgrading the connection protocol to WebSocket.
Note that if you specify these header fields, the server will reject the websocket connection request if authentication fails.
Method 2 - WebSocket Authentication by Sending the Auth Message
Authenticate by Sending the
auth
Message
# # Install wscat from Node.js if you haven't
# npm install -g wscat
APIPATH=stream
APIKEY=BclE7dBGbS1AP3VnOuq6s8fJH0fWbH7r
SECRET=fAZcQRUMxj3eX3DreIjFcPiJ9UR3ZTdgIw8mxddvtcDxLoXvdbXJuFQYadUUsF7q
TIMESTAMP=`date +%s%N | cut -c -13`
MESSAGE=$TIMESTAMP+$APIPATH
SIGNATURE=`echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64`
wscat -c wss://ascendex.com/1/api/v1/pro/stream -w 1 -x "{\"op\":\"auth\", \"id\": \"abc123\", \"t\": $TIMESTAMP, "key": \"$APIKEY\", \"sig\": \"$SIGNATURE\"}"
You can also authenticate a live websocket session by sending an op:auth
message to the server.
Name | Type | Required | Description |
---|---|---|---|
op |
String |
Yes | "auth" |
id |
String |
No | optional id field, you may safely skip it |
t |
Long |
Yes | UTC timestamp in milliseconds, use this timestamp to generate signature |
key |
String |
Yes | your api key |
sig |
String |
Yes | the signature is generated by signing "<timestamp>+stream" |
More comprehensive examples can be found at:
- Python for websocket auth
Authentication Response
Auth success message
{
"m": "auth",
"id": "abc123",
"code": 0
}
Auth error message
{
"m":"auth",
"id": "abc123",
"code": 200006,
"err": "Unable to find User Account Data"
}
You will receive a message for authentication result after you send authentication request.
Field | Type | Description |
---|---|---|
m |
String |
"auth" |
id |
String |
echo back the id if you provide one in the request |
code |
Long |
Any code other than 0 indicate an error in authentication |
err |
Optional[String] |
Provide detailed error message if code is not 0 |
Subscribe to Data Channels
How to Subscribe
Use
wscat
from Node.js to connect to websocket data.
# # Install wscat from Node.js if you haven't
# npm install -g wscat
npm install -g wscat
# Connect to websocket
wscat -c wss://ascendex.com/0/api/pro/v1/stream -x '{"op":"sub", "ch": "depth:ASD/USDT"}'
You can also setup authorized session
@ToDo
You can subscribe/unsubscribe to one or multiple data channels.
- If the subscription is successful, you will receive at least one ack message confirming the request is successful and you will start receiving data streams.
- If the subscription is unsuccessful, you will receive one ack message with text explaining why the subscription failed.
Request Body Schema
The standard messages to subscribe to / unsubscribe from data channels is an JSON object with fields:
Name | Type | Description |
---|---|---|
op |
String |
sub to subscribe and unsub to unsubscribe |
id |
Optional[String] |
user specified UUID, if provided, the server will echo back this value in the response message |
ch |
String |
name of the data channel with optional arguments, see below for details |
Subscribe to bbo stream for symbol
BTC/USDT
{ "op": "sub", "id": "abcd1234", "ch": "bbo:BTC/USDT" }
Subscribe to ref-px stream for symbol
BTC
{ "op": "sub", "id": "abcd1234", "ch": "ref-px:BTC" }
Subscribe to trade stream for a list of symbols
{ "op": "sub", "id": "abcd1234", "ch": "trades:BTC/USDT,ETH/USDT,ASD/USDT" }
Unsubscribes from the depth stream for all symbols (method 1)
{ "op": "unsub", "id": "abcd1234", "ch": "depth:*" }
Unsubscribes from the depth stream for all symbols (methond 2)
{ "op": "unsub", "id": "abcd1234", "ch": "depth" }
Unsubscribes from the 1 minute bar streams for all symbols (method 1)
{ "op": "unsub", "id": "abcd1234", "ch": "bar:1:*" }
Unsubscribes from the 1 minute bar streams for all symbols (method 2)
{ "op": "unsub", "id": "abcd1234", "ch": "bar:1" }
Unsubscribes from bar streams of all frequencies for
ASD/USDT
{ "op": "unsub", "id": "abcd1234", "ch": "bar:*:ASD/USDT" }
Response for sub multiple symbols in one single message
{"m":"sub","id":"abc23g","ch":"summary:BTC/USDT,ASD/USDT","code":0}
Response for unsub multiple symbols in one single message
{ "m": "unsub", "id": "abcd1234", "ch": "bar:*:ASD/USDT" }
Customize Channel content with ch
You can customize the channel content by setting ch
according to the table below:
Type | Value | Description |
---|---|---|
public | depth:<symbol> |
Updates to order book levels. |
public | bbo:<symbol> |
Price and size at best bid and ask levels on the order book. |
public | trades:<symbol> |
Market trade data |
public | bar:<interval>:<symbol> |
Bar data containing O/C/H/L prices and volume for specific time intervals |
public | ref-px:<symbol> |
Reference prices used by margin risk Calculation. |
Private | order:<account> |
Order Update Stream: "cash", "margin", or actual accountId for `account. |
Symbol in ref-px is single asset symbol(e.g. BTC
), not trading pair symbol (e.g. BTC/USDT
), which is different from other channels.
#### Unsubscribe with Wildcard Character *
Using the wildcard character *
, you can unsubscribe from multiple channels with the same channel name.
Subscribe to single or multiple symbols
Subscribe to a single symbol (e.g. BTC/USDT
), or multiple symbols (up to 10) separated by ",", e.g. "BTC/USDT,ETH/USDT"
.
Sub/Unsub response with multiple symbols
When sub or unsub from multiple symbols, we may ack symbol by symbol, or ack in one single message.
You can subscribe/unsubscribe one channel per subscription message. You can subscribe to multiple data channels by sending multiple subscription messages. However, the exchange limits the total number of data channels per client (NOT per session) according to the following rules:
@ToDo rule: maximum number of channels
Channel: Level 1 Order Book Data (BBO)
Subscribe to
ASD/USDT
quote stream
{ "op": "sub", "id": "abc123", "ch":"bbo:ASD/USDT" }
Unsubscribe to
ASD/USDT
quote stream
{ "op": "unsub", "id": "abc123", "ch":"bbo:ASD/USDT" }
BBO Message
{
"m": "bbo",
"symbol": "BTC/USDT",
"data": {
"ts": 1573068442532,
"bid": [
"9309.11",
"0.0197172"
],
"ask": [
"9309.12",
"0.8851266"
]
}
}
You can subscribe to updates of best bid/offer data stream only. Once subscribed, you will receive BBO message whenever the price and/or size changes at the top of the order book.
Each BBO message contains price and size data for exactly one bid level and one ask level.
Channel: Level 2 Order Book Updates
Subscribe to
ASD/USDT
depth updates stream
{ "op": "sub", "id": "abc123", "ch":"depth:ASD/USDT" }
Unsubscribe to
ASD/USDT
depth updates stream
{ "op": "unsub", "id": "abc123", "ch":"depth:ASD/USDT" }
The Depth Message
{
"m": "depth",
"symbol": "ASD/USDT",
"data": {
"ts": 1573069021376,
"seqnum": 2097965,
"asks": [
[
"0.06844",
"10760"
]
],
"bids": [
[
"0.06777",
"562.4"
],
[
"0.05",
"221760.6"
]
]
}
}
If you want to keep track of the most recent order book snapshot in its entirety, the most efficient way is to subscribe to the depth
channel.
Each depth
message contains a bids
list and an asks
list in its data
field. Each list contains a series of [price, size]
pairs that
you can use to update the order book snapshot. In the message, price
is always positive and size
is always non-negative.
- if
size
is positive and theprice
doesn't exist in the current order book, you should add a new level[price, size]
. - if
size
is positive and theprice
exists in the current order book, you should update the existing level to[price, size]
. - if
size
is zero, you should delete the level atprice
.
See Orderbook Snapshot for code examples.
Channel: Market Trades
Subscribe to
ASD/USDT
market trades stream
{ "op": "sub", "id": "abc123", "ch":"trades:ASD/USDT" }
Unsubscribe to
ASD/USDT
market trades stream
{ "op": "unsub", "id": "abc123", "ch":"trades:ASD/USDT" }
Trade Message
{
"m": "trades",
"symbol": "ASD/USDT",
"data": [
{
"p": "0.068600",
"q": "100.000",
"ts": 1573069903254,
"bm": false,
"seqnum": 144115188077966308
}
]
}
The data
field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm
value into one aggregated item. Each trade object contains the following fields:
Name | Type | Description |
---|---|---|
seqnum |
Long |
the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive |
p |
String |
the executed price expressed as a string |
q |
String |
the aggregated traded amount expressed as string |
ts |
Long |
the UTC timestamp in milliseconds of the first trade |
bm |
Boolean |
if true, the buyer of the trade is the maker. |
Channel: Bar Data
Subscribe to
ASD/USDT
1 minute bar stream
{ "op": "sub", "id": "abc123", "ch":"bar:1:ASD/USDT" }
Unsubscribe to
ASD/USDT
1 minute bar stream
{ "op": "unsub", "id": "abc123", "ch":"bar:1:ASD/USDT" }
// Alternatively, you can unsubscribe all bar streams for ASD/USDT
{ "op": "unsub", "id": "abc123", "ch":"bar:*:ASD/USDT" }
// Or unsubscribe all 1 minute bar stream
{ "op": "unsub", "id": "abc123", "ch":"bar:1" }
// Or unsubscribe all bar stream
{ "op": "unsub", "id": "abc123", "ch":"bar" }
Bar Data Message
{
"m": "bar",
"s": "ASD/USDT",
"data": {
"i": "1",
"ts": 1575398940000,
"o": "0.04993",
"c": "0.04970",
"h": "0.04993",
"l": "0.04970",
"v": "8052"
}
}
The data
field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm
value into one aggregated item. Each trade object contains the following fields:
Name | Type | Description |
---|---|---|
seqnum |
Long |
the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive |
p |
String |
the executed price expressed as a string |
q |
String |
the aggregated traded amount expressed as string |
ts |
Long |
the UTC timestamp in milliseconds of the first trade |
bm |
Boolean |
if true, the buyer of the trade is the maker. |
Channel: Order (and Balance)
Subscribe to
cash
account order update stream
{ "op": "sub", "id": "abc123", "ch":"order:cash" }
Subscribe to specific account id cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo account for order update stream
{ "op": "sub", "id": "abc123", "ch":"order:cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo" }
Unsubscribe from
cash
account order update stream
{ "op": "unsub", "id": "abc123", "ch":"order:cash" }
Order update message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"data": {
"s": "BTC/USDT",
"sn": 8159711,
"sd": "Buy",
"ap": "0",
"bab": "2006.5974027",
"btb": "2006.5974027",
"cf": "0",
"cfq": "0",
"err": "",
"fa": "USDT",
"orderId": "s16ef210b1a50866943712bfaf1584b",
"ot": "Market",
"p": "7967.62",
"q": "0.0083",
"qab": "793.23",
"qtb": "860.23",
"sp": "",
"st": "New",
"t": 1576019215402,
"ei": "NULL_VAL"
}
}
Balance Update Message (Cash Account)
{
"m": "balance",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"data": {
"a" : "USDT",
"sn": 8159798,
"tb": "600",
"ab": "600"
}
}
Balance Update Message (Margin Account)
{
"m": "balance",
"accountId": "marOxpKJV83dxTRx0Eyxpa0gxc4Txt0P",
"ac": "MARGIN",
"data": {
"a" : "USDT",
"sn" : 8159802,
"tb" : "400",
"ab" : "400",
"brw": "0",
"int": "0"
}
}
Note: once you subscribe to the order channel, you will start receiving messages from the balance channel automatically. If you unsubscribe from the order channel, you will simultaneously unsubscribe from the balance channel.
You need to specify the account when subscribing to the order channel. You could specify account category cash
, margin
, or specific account id.
Order Messages
You can track the state change of each order thoughout its life cycle with the order update message (m=order
). The data
field is a single order udpate object. Each order update object contains the following fields:
Name | Type | Description |
---|---|---|
s |
String |
symbol |
sn |
long |
sequence number |
ap |
String |
average fill price |
bab |
String |
base asset available balance |
btb |
String |
base asset total balance |
cf |
String |
cumulated commission |
cfq |
String |
cumulated filled qty |
err |
String |
error code; could be empty |
fa |
String |
fee asset |
orderId |
String |
order id |
ot |
String |
order type |
p |
String |
order price |
q |
String |
order quantity |
qab |
String |
quote asset available balance |
qtb |
String |
quote asset total balance |
sd |
String |
order side |
sp |
String |
stop price; could be empty |
st |
String |
order status |
t |
Long |
latest execution timestamp |
ei |
String |
execution instruction |
Balance Messages
You will also receive balance update message (m=balance
) for the asset balance updates not caused by orders. For instance, when you make wallet deposits/withdrawals, or when you transfer asset from the cash account
to the margin account, you will receive balance update message.
For Cash Account Balance Update, the data field contains:
Name | Type | Description |
---|---|---|
a |
String |
asset |
sn |
long |
sequence number |
tb |
String |
total balance |
ab |
String |
available balance |
For Margin Account Balance Update, the data field contains:
Name | Type | Description |
---|---|---|
a |
String |
asset |
sn |
long |
sequence number |
tb |
String |
total balance |
ab |
String |
available balance |
brw |
String |
borrowed amount |
int |
String |
interest amount |
Data Query / Order Request
Besides subscript mesages, you could also send request message via websocket. You will receive exactly one message regarding each request message. Here are some use cases:
- Place/cancel orders
- Request orderbook snapshot data to initialize/rebuild orderbook.
WebSocket Request Schema
All operation or data request follow the same uniform format:
Name | Type | Required | Value | Description |
---|---|---|---|---|
op | String |
Yes | req |
|
id | String |
No | digits and numbers | if provided, the server will echo back this value in the response message |
action | String |
Yes | See below | name of the request action with optional arguments |
account | String |
NO | cash , margin |
the account of the interest, this field is not required for public data request |
args | {key:value} |
No | each action has different args, please see each action for detail. |
Supported action
Name | Description |
---|---|
place-order | Place new order |
cancel-order | Cancel exisitng open order |
cancel-all | Cancel all open orders on account level |
depth-snapshot | Get market depth for symbol up to 500 level |
depth-snapshot-top100 | Get top 100 depth |
market-trades | Get market trades for a symbol |
balance | Request balance |
open-order | Query open order |
margin-risk | Get margin risk |
WebSocket Response Schema
We try to provide all data in uniform format.
Ack or Data
Response follow the following schema
Name | Type | Description |
---|---|---|
m | String |
message topic related with request action |
id | Optional[String] |
user specified UUID, if provided, the server will echo back this value in the response message |
action | String |
echo action field in request |
data or info | Json |
detailed data for data request, or info for operation result(e.g. order place/cancel) |
Error
Name | Type | Description |
---|---|---|
m | String |
"error" |
id | String |
Echo back the error |
code | Long |
|
reason | String |
simple error message |
info | String |
detailed error message |
Example error response
{
"m": "error",
"id": "ab123",
"code": 100005,
"reason": "INVALID_WS_REQUEST_DATA",
"info": "Invalid request action: trade-snapshot"
}
WS: Orderbook Snapshot
Requesting the current order book snapshot
{ "op": "req", "id": "abcdefg", "action": "depth-snapshot", "args": { "symbol": "ASD/USDT" } }
Depth snapshot message
{
"m": "depth-snapshot",
"symbol": "ASD/USDT",
"data": {
"seqnum": 3167819629,
"ts": 1573142900389,
"asks": [
[
"0.06758",
"585"
],
[
"0.06773",
"8732"
]
],
"bids": [
[
"0.06733",
"667"
],
[
"0.06732",
"750"
]
]
}
}
You can request the current order book via websocket by an depth-snapshot
request.
The args
schema:
Name | Data Type | Description |
---|---|---|
op |
String |
req |
action |
String |
depth-snapshot |
id |
String |
echo back in case of error |
args:symbol |
String |
Symbol, e.g. ASD/USDT |
The response schema:
Name | Data Type | Description |
---|---|---|
m |
String |
depth-snapshot |
symbol |
String |
Symbol, e.g. ASD/USDT |
data:seqnum |
Long |
|
data:ts |
Long |
UTC Timestamp in milliseconds |
data:asks |
[[String, String]] |
List of (price, size) pair |
data:bids |
[[String, String]] |
List of (price, size) pair |
You can following the steps below to keep track of the the most recent order book:
- Connecting to WebSocket Stream
- Subscribe to the depth update stream, see Level 2 Order Book Updates.
- Send a
depth-snapshot
request to the server. - Once you obtain the snapshot message from the server, initialize the snapshot.
- Using consequent
depth
messages to update the order book.
Please note that field seqnum
should strictly increase by 1 for each new depth update (each symbol
maintain its own seqnum
).
If you see a larger than 1 gap from previous seqnum
(for the same symbol
), then there might be data loss,
you need to repeat above steps to maintain a new order book.
The depth-snapshot
message is constructed in a consistent way with all depth
message.
Please note that the depth-snapshot
API has higher latency. The response time is usually between
1000 - 2000 milliseconds. It is intended to help you initialize the orderbook, not to be used to obtain
the timely order book data.
More comprehensive examples can be found at:
- Python: websocket orderbook snapshot
WS: Place Order
Request to place new order
{
"op": "req",
"action": "place-Order",
"account": "cash",
"args": {
"time": 1573772908483,
"id": "11eb9a8355fc41bd9bf5b08bc0d18f6b",
"symbol": "EOS/USDT",
"orderPrice": "3.27255",
"orderQty": "30.557210737803853",
"orderType": "limit",
"side": "buy",
"postOnly": false,
"respInst": "ACK"
}
}
Successful ACK message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "place-order",
"status": "Ack",
"info": {
"symbol": "BTC/USDT",
"orderType": "Limit",
"timestamp": 1576015701441,
"id": "17e1f6809122469589ffc991523b505d",
"orderId": "s16ef1daefbe08669437121523b505d"
}
}
Error response message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "place-order",
"status": "Err",
"info": {
"id": "69c482a3f29540a0b0d83e00551bb623",
"symbol": "ETH/USDT",
"code": 300011,
"message": "Not Enough Account Balance",
"reason": "INVALID_BALANCE"
}
}
Place order via websocket
Request
Make new order request follow the general websocket request rule, with proper place new order parameters as specified in rest api for args field.
see placing order via RESTful API.
Response
Respond with m field as order, and action field as place-order; status field to indicate if this is a successful Ack or failed Err.
ACK
With status field as Ack to indicate this new order request pass some basic sanity check, and has been sent to matching engine.
info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide server side generated orderId, which is the id you should use for future track or action on the order.
ERR
With status field as Err to indicate there is some obvisous errors in your order.
info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide error code, reason, and message detail.
WS: Cancel Order
Request to cancel existing open order
{
"op": "req",
"action": "cancel-Order",
"account": "cash",
"args": {
"time": 1574165050128,
"id": "2d4c3fa1e5c249e49f990ce86aebb607",
"orderId": "16e83845dcdsimtrader00008c645f67",
"symbol": "ETH/USDT"
}
}
Successful ACK message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "cancel-order",
"status": "Ack",
"info": {
"symbol": "ETH/USDT",
"orderType": "NULL_VAL",
"timestamp": 1574165050147,
"id": "7b73dcd8e8c847d5a99df5ef5ae5088b",
"orderId": "16e83845dcdsimtrader00008c645f67"
}
}
Error response message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "cancel-order",
"status": "Err",
"info": {
"code": 300006,
"id": "x@fabs",
"message": "Invalid Client Order Id: x@fabs",
"symbol": "ETH/USDT",
"reason": "INVALID_ORDER_ID"
}
}
Cancel an existing open order via websocket
Request
Make order cancelling request follow the general websocket request rule by setting action
to be cancel-orde
, with proper cancel order parameters as specified in rest api for args field.
Response
ACK
With status field as Ack to indicate this cancel order request pass some basic sanity check, and has been sent to matching engine.
info field provide some detail: if you provide id in your request, it will be echoed back as id to help you idintify; we also echo back target orderId to be cancelled.
Err
With status field as Err to indicate there is some obvisous errors in your cancel order request.
info field provide some detail: if you provide id in your request, it will be echoed back as id to help you identify; we also provide error code, reason, and message detail.
WS: Cancel All Orders
Request to cancel all existing open orders
{
"op": "req",
"action": "cancel-All",
"args": {}
}
Request to cancel existing open order related to symbol "BTC/USDT"
{
"op": "req",
"action": "cancel-All",
"account": "cash",
"args": {
"symbol": "BTC/USDT"
}
}
Successful ACK message
{
"m": "order",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"action": "cancel-all",
"status": "Ack",
"info": {
"symbol": "",
"orderType": "NULL_VAL",
"timestamp": 1574165159732,
"id": "69c482a3f29540a0b0d83e00551bb623",
"orderId": ""
}
}
Cancel all open orders on account level via websocket with optional symbol.
Request
Make general websocket request with action
field as cancel-All
and set proper account
value(cash
, or margin
), and provide time value in args.
Response
With status field as Ack to indicate this cancel all order request has been received by server and sent to matching engine.
info field provide some detail: if you provide id in your request, it will be echoed back as id to help you match ack with request.
WS: Query Open Orders on Symbol
Requesting open orders on symbol BTC/USDT
{
"op": "req",
"action": "open-order",
"id": "abdad113",
"account": "cash",
"args": {
"symbols": "BTC/USDT"
}
}
Open orders response
{
"m": "open-order",
"id": "abdad113",
"accountId": "cshQtyfq8XLAA9kcf19h8bXHbAwwoqDo",
"ac": "CASH",
"data": [
{
"sn": 103,
"orderId": "a16edce82c6e0866943712UKrJP1HCA",
"s": "BTC/USDT",
"ot": "Limit",
"t": 1575664233699,
"p": "9000",
"q": "0.01",
"sd": "Buy",
"st": "New",
"ap": "0",
"cfq": "0",
"sp": "0",
"err": "NULL_VAL",
"btb": "0",
"bab": "0",
"qtb": "0",
"qab": "0",
"cf": "0",
"fa": "USDT"
},
...
]
}
You can request the open order via websocket by an open-order
request.
The request schema:
Name | Data Type | Description |
---|---|---|
op |
String |
req |
action |
String |
open-order |
id |
String |
for result match purpose |
account |
String |
cash , margin |
args:symbols |
Optional[String] |
add the (optional) symbol filter, see below for details. |
The symbols
key in the args
map allows you to customize the symbol filter in a flexible way:
- to query open orders of the a specific symbol, set
symbols
to a valid symbol code. For instance,{"symbols": "BTC/USDT"}
- to query open orders of multiple symbols, set
symbols
to comma separated string of valid symbol codes. For instance,{"symbols": "BTC/USDT,ETH/USDT"}
allows you to query open orders of bothBTC/USDT
andETH/USDT
at the same time. - to query all open orders, you may either use the wild card (
{"symbols": "*"}
) or simply omit thesymbols
key ({}
).
The response schema:
Name | Data Type | Description |
---|---|---|
m |
String |
open-order |
accountId |
String |
account |
ac |
String |
cash , margin |
id |
String |
echo id in request |
data |
Order Json Array |
A list of open order json objects |
WS: Recent Market Trades
Requesting the most recent 12 trades for symbol ASD/USDT
{ "op": "req", "action": "market-trades", "args": { "symbol": "ASD/USDT", "level": 12} }
Trades snapshot message
{
"m": "market-trades",
"id": "abcd1334",
"symbol": "ASD/USDT",
"data": [
{
"p": "0.068600",
"q": "100.000",
"ts": 1573069903254,
"bm": false,
"seqnum": 144115188077966308
}
]
}
You can request the current order book via websocket by an market-trades
request.
The request schema:
Name | Data Type | Description |
---|---|---|
op |
String |
req |
action |
String |
market-trades |
args |
{key:value} |
see args below for detail |
The args
schema:
symbol
| String
| Symbol, e.g. ASD/USDT
level
| Int | Number of trades to request
The response schema:
Name | Data Type | Description |
---|---|---|
m |
String |
market-trades |
symbol |
String |
Symbol, e.g. ASD/USDT |
data |
Json Array |
A list of trade json objects |
The data
field is a list containing one or more trade objects. The server may combine consecutive trades with the same price and bm
value into one aggregated item. Each trade object contains the following fields:
Name | Type | Description |
---|---|---|
seqnum |
Long |
the sequence number of the trade record. seqnum is always increasing for each symbol, but may not be consecutive |
p |
String |
the executed price expressed as a string |
q |
String |
the aggregated traded amount expressed as string |
ts |
Long |
the UTC timestamp in milliseconds of the first trade |
bm |
Boolean |
if true, the buyer of the trade is the maker. |
WS: Margin Risk for Symbol
Request margin risk for symbol
BTC/USDT
{
"op": "req",
"action": "margin-risk",
"id": "abcefg",
"account": "margin",
"args": {
"symbol": "BTC/USDT"
}
}
Margin Risk Response
{
"m":"margin-risk",
"accountId":"marGad02EnGqSo6P2SMBoNUX4lGyxjsy",
"ac":"MARGIN",
"id":"abcefg",
"data": {
"tb":"14058.242182715",
"ab":"14058.242182715",
"nb":"14058.242182715",
"eim":"0",
"emm":"0",
"clv":"1",
"ilv":"3",
"alv":"10",
"cus":"-1",
"pts":"0"
}
}
You can request margin risk for a symbol via websocket by an margin-risk
request.
The args
schema:
Name | Data Type | Description |
---|---|---|
op |
String |
req |
action |
String |
margin-risk |
id |
String |
for result match purpose |
args:symbol |
String |
Symbol, e.g. ASD/USDT |
The response schema:
Name | Data Type | Description |
---|---|---|
m |
String |
margin-risk |
accountId |
String |
margin accountId |
ac |
String |
MARGIN |
symbol |
String |
Symbol, e.g. ASD/USDT |
id |
String |
echo back id in request |
data |
Json |
See data detail below |
data
field detail
Name | Data Type | Description |
---|---|---|
tb |
String |
total balance |
ab |
String |
available balance |
nb |
String |
net balance |
eim |
String |
effective initial margin |
emm |
String |
effective maintaince margin |
clv |
String |
current leverage |
ilv |
String |
initial leverage |
alv |
String |
account max leverage |
cus |
String |
cushion |
pts |
String |
points balance |
Experimental APIs
Real Time Level 2 Orderbook Updates
WebSocket messages from the default depth
channel are throttled with 300 milliseconds throttling intervals. If you want to
subscribe to realtime orderbook updates, please refer to this article.
Subscribe to Order Channel with Ready Ack Mode
By default, when you subscribe to the order channel via WebSocket, you automatically enter the New Ack Mode. In this mode, when the
order is accepted by the matching engine, you will receive an order message with status st=New
. This is true even when the order will
immediately change status. For instance, when you place a Post-only order that crosses the book, it will immediately be rejected. However,
in the New Ack Mode, you will first receive an order message with st=New
, then immediately receive another message with st=Canceled
. However,
if your order successfully enters the orderbook without crossing with order on the opposite side, you will only receive one message with st=New
.
This makes it hard for trading bots to decide when to take actions.
To address this issue, we introduced the Ready Ack mode. Follow this link for more details.
Appendex
ENUM: BlockChains
ABBC Coin
Akash
Algorand
ATOM
BandProtocol
BCH-SLP
BEP20
Binance
Bitcoin
Bitcoin ABC
Bitcoin Cash ABC
Bitcoin HD
Bitcoin SV
bytom
Cardano
casper
Dash
Divi
dogechain
e-Money
Elrond eGold
EOS
ERC20
Ether Zero
Ethereum Classic
Filecoin
FIOProtocol
fusion
GO20
Harmony
Hathor
hermez
HPB
insolar
Iost chain
kava
Litecoin
LTONetwork
Matic network
MetaHash
NEO
nervos
Nimiq
Omni
oneledger
Ontology
Own blockchain
Persistence
polkadot
Qtum
Raven
Ripple
Solana
Stafi
Stellar
Tezos
Tron
vechain
wanchain
xDai
XEM
YAP STONE
Zerocash
Zilliqa
Error Message
We structure our error message in three levels: * Error Group provide a broad error category (Error group id = error code / 10000) * Error Reason provide some intuitive information on the error * Error Message explains error detail.
In most situation, we provide simple error in this way: {"code": XYABCDE, "reason": XXXXXXXX}; for complicated scenatio (such as order place/cancel request, websocket request, and so on), we provide rich format error: {"code": XYZBCDE, "reason":XXXXXXXX, "message":YYYYYYYY}.
Rich format error is derived from simple error, so you could get error message with same error code and reason, but different message content.
Error Base Group
We summary the major error group below.
group name | group code | derived code | description |
---|---|---|---|
GeneralError | 10 | 10XXXX | Errors applied to general scenario |
FormatError | 15 | 15XXXX | Format related error |
AuthError | 20 | 20XXXX | Auth related error |
OrderError | 30 | 30XXXX | Order action and information related error |
MarginError | 31 | 31XXXX | Margin account and trading related error |
SystemError | 50 | 50XXXX | System related error |
BehaviorError | 90 | 90XXXX | Behavior error |
10XXXX - General Error
code | reason | descripion |
---|---|---|
100001 | INVALID_HTTP_INPUT | Http request is invalid |
100002 | DATA_NOT_AVAILABLE | Some required data is missing |
100003 | KEY_CONFLICT | The same key exists already |
100004 | INVALID_REQUEST_DATA | The HTTP request contains invalid field or argument |
100005 | INVALID_WS_REQUEST_DATA | Websocket request contains invalid field or argument |
100006 | INVALID_ARGUMENT | The arugment is invalid |
100007 | ENCRYPTION_ERROR | Something wrong with data encryption |
100008 | SYMBOL_ERROR | Symbol does not exist or not valid for the request |
100009 | AUTHORIZATION_NEEDED | Authorization is require for the API access or request |
100010 | INVALID_OPERATION | The action is invalid or not allowed for the account |
100011 | INVALID_TIMESTAMP | Not a valid timestamp |
100012 | INVALID_STR_FORMAT | String format does not |
100013 | INVALID_NUM_FORMAT | Invalid number input |
100101 | UNKNOWN_ERROR | Some unknown error |
15XXXX - Format Error
code | reason | descripion |
---|---|---|
150001 | INVALID_JSON_FORMAT | Require a valid json object |
20XXXX - Auth Error
Auth related errors.
code | reason | descripion |
---|---|---|
200001 | AUTHENTICATION_FAILED | Authorization failed |
200002 | TOO_MANY_ATTEMPTS | Tried and failed too many times |
200003 | ACCOUNT_NOT_FOUND | Account not exist |
200004 | ACCOUNT_NOT_SETUP | Account not setup properly |
200005 | ACCOUNT_ALREADY_EXIST | Account already exist |
200006 | ACCOUNT_ERROR | Some error related with error |
200007 | CODE_NOT_FOUND | |
200008 | CODE_EXPIRED | Code expired |
200009 | CODE_MISMATCH | Code does not match |
200010 | PASSWORD_ERROR | Wrong assword |
200011 | CODE_GEN_FAILED | Do not generate required code promptly |
200012 | FAKE_COKE_VERIFY | |
200013 | SECURITY_ALERT | Provide security alert message |
200014 | RESTRICTED_ACCOUNT | Account is restricted for certain activity, such as trading, or withdraw. |
200015 | PERMISSION_DENIED | No enough permission for the operation |
30XXXX - Order Error
Order place/cancel/query related errors. We usually provide rich format errors based on these simple ones.
code | reason | descripion |
---|---|---|
300001 | INVALID_PRICE | Order price is invalid |
300002 | INVALID_QTY | Order size is invalid |
300003 | INVALID_SIDE | Order side is invalid |
300004 | INVALID_NOTIONAL | Notional is too small or too large |
300005 | INVALID_TYPE | Order typs is invalid |
300006 | INVALID_ORDER_ID | Order id is invalid |
300007 | INVALID_TIME_IN_FORCE | Time In Force in order request is invalid |
300008 | INVALID_ORDER_PARAMETER | Some order parameter is invalid |
300009 | TRADING_VIOLATION | Trading violation on account or asset |
300011 | INVALID_BALANCE | No enough account or asset balance for the trading |
300012 | INVALID_PRODUCT | Not a valid product supported by exchange |
300013 | INVALID_BATCH_ORDER | Some or all orders are invalid in batch order request |
300020 | TRADING_RESTRICTED | There is some trading restriction on account or asset |
300021 | TRADING_DISABLED | Trading is disabled on account or asset |
300031 | NO_MARKET_PRICE | No market price for market type order trading |
31XXXX - Margin Error
Margin trading related errors.
code | reason | descripion |
---|---|---|
310001 | INVALID_MARGIN_BALANCE | No enough margin balance |
310002 | INVALID_MARGIN_ACCOUNT | Not a valid account for margin trading |
310003 | MARGIN_TOO_RISKY | Leverage is too high |
310004 | INVALID_MARGIN_ASSET | This asset does not support margin trading |
310005 | INVALID_REFERENCE_PRICE | There is no valid reference price |
50XXXX - System Error
code | reason | descripion |
---|---|---|
510001 | SERVER_ERROR | Something wrong with server. |
90XXXX - Behavior Error
code | reason | descripion |
---|---|---|
900001 | HUMAN_CHALLENGE | Human change do not pass |