API General Info
The Secure Web APIs are designed to allow client applications to view and update data using the HTTPS(rest) and WSS(websocket) protocol over the internet. The purpose of this document is to provide the urls and the specification of the messages communicated through Web APIs.
Message Format
All messages are in json format.
Message Field Types
Type | Description |
---|---|
Integer | Integer numbers |
Long | Long numbers |
Boolean | True/False |
DoubleString | Decimal numbers are returned as strings to preserve full precision across platforms |
Enum | Enum definition. Passing invalid enum values will result in API_BAD_REQUEST error |
String | Text |
Timestamp
Unless otherwise specified, all timestamps returned from API are milliseconds since UNIX Epoch.
Mandatory Field Indicators
Indicator | Description |
---|---|
M | Mandatory field |
(M) | Mandatory field under certain conditions |
O | Optional field |
REST API General Info
Base Url and Message Format
https://api.xxxx.com/
All requests and responses use application/json content type. Responses follow HTTP response status codes to indicate the success and the failure.
Success/Error Response
Successful http response contains HTTP status code 200 and an optional body. If the response contains the body, the fields within the body are documented in each related API sections. Failed http response contains non 200 HTTP status code and the body with an errorCode field to indicate the cause of the failures.
Error Response Fields
Name | Type | Mandatory | Description |
---|---|---|---|
errorCode | String | M | Error code. e.g.INVALID_PASSWORD |
errorData | String | O | Additional information on the user data that may cause the error. Data is provided in json format. |
Error Codes
Overview:
If an error occurs during the processing of an API request, the API will return an error to the caller. The general flow of information to check is:
- status code of the response.
- error code and other information in the response body (JSON)
HTTP Status Codes:
Status Code | Description |
---|---|
400 - Bad Request | The request was wrong, often due to a missing or invalid parameter. See the error code and response data for more details. |
401 - Unauthorized | The request failed to authenticate (example: a valid api key was not included in your request header) |
403 - Forbidden | The provided api key is not authorized to perform the requested operation (example: attempting to trade with an api key not authorized to make trades) |
404 - Not Found | The requested resource does not exist. |
409 - Conflict | The request parameters were valid but the request failed due to an operational error. (example: EXCEED_BALANCE) |
429 - Too Many Requests | Too many requests hit the API too quickly. Please take a break to relieve the pressure on your fingers. |
500 - Internal Server Error | The server encountered an error and was unable to complete the request. |
502 - Bad Gateway | The server received an invalid response from the upstream server. |
503 - Service Unavailable | The request parameters were valid but the request failed because the service is temporarily unavailable. |
Pagination
Pagination is supported for all REST calls that return arrays. The newest items are returned by default.
Name | Type(value) | Mandatory | Description |
---|---|---|---|
pageNumber | Integer | O | Default to 1 |
pageSize | Integer | O | Default to 100 |
Example: GET api/orders?pageNumber=1&pageSize=100
Rate Limits
- Throttle public endpoints by IP: 5 requests per second
- Throttle authenticated endpoints by user ID: 5 requests per second
- Most endpoint request counts as one request.
- For certain endpoint requests, each request counts as more than 1 due to extra system processing resources required. The doc for such endpoints should contain the weight information which indicates the number of requests it counts for.
- When the rate limit is exceeded, a status of 429 will be returned.
Websocket API General Info
wss://ws-api.xxxx.com
All messages sent and received through websocket are encoded in JSON format. All messages have a type attribute that can be used to handle the message.
Failures will cause an error message to be emitted with errorCode.
Error Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | error | M | Error message type |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
errorCode | String | M | Error code |
REST Public
All Instruments
curl "https://api.xxxx.com/api/instruments"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/instruments", true);
xhr.send();
}
Sample response:
[
{
"instrumentType": "SPOT",
"minOrderPrice": "0.00001",
"minOrderSize": "0.001",
"instrumentId": "ETH-BTC",
"lotSize": "0.001",
"maxOrderSize": "100000",
"assetId": "ETH",
"quoteAssetId": "BTC",
"tickSize": "0.00001",
"maxOrderPrice": "100000"
}
]
Http request
METHOD: GET
PATH: /api/instruments
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. BTC-USD |
assetId | String | M | e.g. BTC |
quoteAssetId | String | M | e.g. USD |
instrumentType | Enum | M | |
tickSize | DoubleString | M | price increment |
lotSize | DoubleString | M | size increment |
minOrderPrice | DoubleString | M | |
maxOrderPrice | DoubleString | M | |
minOrderSize | DoubleString | M | |
maxOrderSize | DoubleString | M | |
expiry | Long | (M) | Mandatory for FUTURES instrument |
underlying | String | (M) | Mandatory for FUTURES instrument |
contractMultiplier | Integer | (M) | Mandatory for FUTURES instrument |
Order Book
curl "https://api.xxxx.com/api/orderbooks/ETH-BTC?level=1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/orderbooks/ETH-BTC?level=1", true);
xhr.send();
}
Sample response:
{
"sequence": "0",
"lastModifiedTime": 1545990730713,
"level": 1,
"instrumentId": "ETH-BTC",
"asks": [
{
"size": "6.348",
"price": "0.03227",
"numOfOrders": 1
}
],
"bids": [
{
"size": "1.268",
"price": "0.03226",
"numOfOrders": 1
}
]
}
Weight: 5
Http request
METHOD: GET
PATH: /api/orderbooks/{instrumentId}
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
level | Integer | M | 1 - top bid and ask; 2 - order book; 3 - full order level book |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
lastModifiedTime | Long | M | |
bookLevel | Integer | M | 1/2/3 |
sequence | Long | M | |
bids | Array of [price, size, numOfOrders/orderId] | M | Level 1 - This is one sized array;Level 2 - The aggregated size for each price level is returned with numOfOrders count for the price;Level 3 - The order level information is returned |
asks | Array of [price, size, numOfOrders/orderId] | M | Level 1 - This is one sized array;Level 2 - The aggregated size for each price level is returned with numOfOrders count for the price;Level 3 - The order level information is returned |
Trades
curl "https://api.xxxx.com/api/trades/ETH-BTC"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/trades/ETH-BTC", true);
xhr.send();
}
Sample response:
[
{
"side": "BUY",
"size": "0.01",
"instrumentId": "ETH-BTC",
"price": "0.0323",
"createdTime": 1545991656158,
"tradeId": "448679"
},
{
"side": "BUY",
"size": "0.01",
"instrumentId": "ETH-BTC",
"price": "0.0323",
"createdTime": 1545991656146,
"tradeId": "448678"
},
{
"side": "BUY",
"size": "0.01",
"instrumentId": "ETH-BTC",
"price": "0.0323",
"createdTime": 1545991656133,
"tradeId": "448677"
},
{
"side": "BUY",
"size": "0.01",
"instrumentId": "ETH-BTC",
"price": "0.0323",
"createdTime": 1545991656121,
"tradeId": "448676"
}
]
Returns most recent trades in an array.
Http request
METHOD: GET
PATH: /api/trades/{instrumentId}
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
createdTime | Long | M | |
tradeId | String | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M |
Ticker
curl "https://api.xxxx.com/api/tickers/ETH-BTC"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/tickers/ETH-BTC", true);
xhr.send();
}
Sample response:
{
"24hLow": "0.03146",
"24hVolume": "5514.332",
"lastModifiedTime": 1545990354807,
"bestAsk": "0.03249",
"instrumentId": "ETH-BTC",
"24hHigh": "0.0334",
"24hChange": "-0.00083",
"lastPrice": "0.03248",
"bestBid": "0.03248"
}
Http request
METHOD: GET
PATH: /api/tickers/{instrumentId}
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. "ETH-BTC" |
lastModifiedTime | Long | M | |
lastPrice | DoubleString | M | |
bestBid | DoubleString | M | |
bestAsk | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M |
All Tickers
curl "https://api.xxxx.com/api/tickers"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/tickers", true);
xhr.send();
}
Sample response:
[
{
"24hLow": "0.03146",
"24hVolume": "5514.332",
"lastModifiedTime": 1545990442807,
"bestAsk": "0.03249",
"instrumentId": "ETH-BTC",
"24hHigh": "0.0334",
"24hChange": "-0.00083",
"lastPrice": "0.03248",
"bestBid": "0.03248"
}
]
Http request
METHOD: GET
PATH: /api/tickers
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. "ETH-BTC" |
lastModifiedTime | Long | M | |
lastPrice | DoubleString | M | |
bestBid | DoubleString | M | |
bestAsk | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M |
Charts
curl "https://api.xxxx.com/api/charts/ETH-BTC?startTime=1545990160243&interval=60"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/charts/ETH-BTC?startTime=1545990160243&interval=60", true);
xhr.send();
}
Sample response:
[
{
"volume": "1.030",
"high": "0.03234",
"low": "0.03228",
"openPrice": "0.03234",
"startTime": 1545993300000,
"closePrice": "0.03228"
},
{
"volume": "14.723",
"high": "0.03235",
"low": "0.03225",
"openPrice": "0.03225",
"startTime": 1545993000000,
"closePrice": "0.03234"
},
{
"volume": "3.630",
"high": "0.03234",
"low": "0.03222",
"openPrice": "0.03234",
"startTime": 1545992700000,
"closePrice": "0.03223"
}
]
It returns an array of data point stats.
Http request
METHOD: GET
PATH: /api/charts/{instrumentId}
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
startTime | Long | M | Milliseconds since Unix Epoch |
endTime | Long | O | Milliseconds since Unix Epoch |
interval | Integer | M | In seconds; 60/300/900/3600/21600/86400;The combination of startTime, endTime and granularity determines how many data points obtained. The maximum supported number of data points is xxx |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
lastModifiedTime | Long | O | |
startTime | Long | M | |
endTime | Long | M | |
openPrice | String | M | |
closePrice | String | M | |
low | String | M | |
high | String | M | |
volume | String | M |
Time
curl "https://api.xxxx.com/api/time"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/time", true);
xhr.send();
}
Sample response:
{
"time": 1545994698933
}
It returns the server time in milliseconds since Unix Epoch
Http request
METHOD: GET
PATH: /api/time
REST Private
Authentication
All requests to authenticated endpoints require authentication by providing API key, signature, timestamp and passcode.
API Key
Before being able to send any requests, you must create API key via the exchange website. Upon creation, you will be provided:
- Key (Generated by exchange)
- Secret (Generated by exchange)
- Passcode (Provided by user and exchange stores the salted hash of the passcode to further secure the api access)
API Key Permissions
You can restrict the functionality of API keys.
- TRADE_VIEW
- OpenOrders
- AllOrders
- Fills
- TRADE
- New Order
- Cancel Order
- Cancel All Order
- ACCOUNT_VIEW
- Accounts
- Account Transactions
- WITHDRAW
- Withdraw
Sending a Request
//Code for generate API-SIGN
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class ApiSignGenerator {
public static String generateApiSign(long timestamp, String method, String path, String apiSecret) throws NoSuchAlgorithmException, InvalidKeyException {
String algorithm = "HmacSHA256";
String message = timestamp + (method == null ? "" : method.toUpperCase()) + (path == null ? "" : path);
byte[] encodedSecret = Base64.getEncoder().encode(apiSecret.getBytes());
SecretKeySpec secretKeySpec = new SecretKeySpec(encodedSecret, algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(secretKeySpec);
byte[] bytes = mac.doFinal(message.getBytes());
return new String(Hex.encodeHex(bytes));
}
// If you want sent request to "https://api.xxxx.com/api/accounts", you can generate sign by doing this:
public static void getAccounts() throws InvalidKeyException, NoSuchAlgorithmException {
long timestamp = 1553596255786L; // System.currentTimeMillis();
String method = "GET";
String path = "/api/accounts";
String apiSecret = "NCtRU0JwZWZnVFVDZmlMRFduMk1hTFZDM05vS3g1Z3E1c1h6blB0RmxXRT0=";
String apiSign = generateApiSign(timestamp, method, path, apiSecret);
System.out.println("apiSign:" + apiSign);
// The console will print:"apiSign:e4c8f42e18b551dcebd5801bfa254498e98d20e0a5322b30c78a7004aa5a2669"
}
}
//Code for generate API-SIGN
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Base64/1.0.1/base64.js"></script>
<script type="text/javascript">
function generateApiSign(timestamp, method, path, apiSecret) {
var message = timestamp + method + path;
var encodedSecret = window.btoa(apiSecret);
return CryptoJS.HmacSHA256(message, encodedSecret).toString();
};
// If you want sent request to "https://api.xxxx.com/api/accounts", you can generate sign by doing this:
function getAccounts() {
var timestamp = 1553596255786;//new Data().getMilliseconds();
var method = "GET";
var path = "/api/accounts";
var apiSecret = "NCtRU0JwZWZnVFVDZmlMRFduMk1hTFZDM05vS3g1Z3E1c1h6blB0RmxXRT0=";
var apiSign = generateApiSign(timestamp, method, path, apiSecret);
console.info("apiSign:" + apiSign);
// The console will print:"apiSign:e4c8f42e18b551dcebd5801bfa254498e98d20e0a5322b30c78a7004aa5a2669"
};
</script>
All requests must contain the following headers:
- API-KEY The api key
- API-SIGN The hex-encoded signature by creating a sha256 HMAC using the base64 encoded secret Key on the prehash string timestamp + method + path and hex-encode the output
- API-TIMESTAMP The same timestamp used in the signature. It should be in seconds since UNIX Epoch.
- API-PASSCODE The passcode provided during api key creation
The timestamp must be within 5 seconds of the serve time or your request will be considered expired and rejected. To change 5 seconds expiry time, you could set the optional field API-EXPIRY in header with a number in seconds. Please use /time endpoint to query for the server time if you believe there many be time skew between your server and our servers.
Place An Order
curl "https://api.xxxx.com/api/orders"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
-X "POST"
-H "Content-Type:application/json"
-d '{"postOnly":true,"orderType":"LIMIT","side":"SELL","size":"0.1","instrumentId":"ETH-BTC","price":"0.0328","timeInForce":"GTC"}'
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("POST", "https://api.xxxx.com/api/orders", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.setRequestHeader("Content-Type","application/json");
var data = '{"postOnly":true,"orderType":"LIMIT","side":"SELL","size":"0.1","instrumentId":"ETH-BTC","price":"0.0328","timeInForce":"GTC"}';
xhr.send(data);
}
Sample response:
{
"orderId": "fb2b1b09-56ff-4c37-9f59-4170c55f2364",
"clientOrderId": "",
"timestamp": 1546056658895
}
Http request
METHOD: POST
PATH: /api/orders
Request Parameters:
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
orderType | Enum | M | |
price | DoubleString | (M) | Mandatory in LIMIT order |
size | DoubleString | (M) | Mandatory in LIMIT order; Mandatory in MARKET order if quoteAmount is not provided |
quoteAmount | DoubleString | (M) | Amount in quote asset term. Mandatory in MARKET order if size is not provided |
side | Enum | M | |
timeInForce | Enum | O | Default to GTC for LIMIT orders |
clientOrderId | String | O | Provided by user |
stopType | Enum | O | Only used in stop orders |
stopPrice | NumberString | (M) | Mandatory if stopType is specified |
postOnly | Boolean | O | Default to false. If any part of the order results in taking liquidity, the order will be rejected and no part of it will execute. |
selfTradePrevention | Enum | O | Default to CO - cancel the oldest |
orderRouting | Boolean | O | Default to false. |
Mandatory fields based on order type:
orderType | Mandatory Fields |
---|---|
LIMIT | price, size |
MARKET | size or quoteAmount |
STOP_ENTRY | quoteAmount(buy order), stopPrice |
STOP_ENTRY_LIMIT | price, size, stopPrice |
STOP_LOSS | size(sell order), stopPrice |
STOP_LOSS_LIMIT | price, size, stopPrice |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
clientOrderId | String | (M) | Mandatory if clientOrderId is provided by the user |
orderId | String | M | System generated unique order id |
timestamp | Long | M | Time when the order is accepted with order status of PENDING_NEW |
Cancel An Order
curl "https://api.xxxx.com/api/orders/3071ede3-20ab-4b9e-a6eb-9d56e61e4165"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
-X "DELETE"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("DELETE", "https://api.xxxx.com/api/orders/3071ede3-20ab-4b9e-a6eb-9d56e61e4165", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.setRequestHeader("Content-Type","application/json");
xhr.send();
}
Sample response:
{
"orderId": "3071ede3-20ab-4b9e-a6eb-9d56e61e4165",
"timestamp": 1546056658895
}
Http request
METHOD: DELETE
PATH: /api/orders/{orderId}
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
orderId | String | M | |
timestamp | Long | M | When the cancel is accepted and order status is updated to PENDING_CANCEL |
Cancel All Order
curl "https://api.xxxx.com/api/orders"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
-X "DELETE"
-H "Content-Type:application/json"
-d '{"instrumentId":"ETH-BTC"}'
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("DELETE", "https://api.xxxx.com/api/orders", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.setRequestHeader("Content-Type","application/json");
var data = '{"instrumentId":"ETH-BTC"}';
xhr.send(data);
}
Sample response:
{
"orderIds": [
"8a7d9589-4ad0-415e-b8b8-e04fc573408d",
"8f7a652b-9b4d-42ed-8bb6-f1d331b5cf48"
]
}
This is to cancel all open orders with best effort.
Http request
METHOD: DELETE
PATH: /api/orders
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | O | Cancel all orders for the specified instrument. Default to cancel orders under all instruments |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
orderIds | Array of Strings | M | Orders that are being cancelled in the system |
Get Open Orders
curl "https://api.xxxx.com/api/orders"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/orders", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
{
"records": [
{
"selfTradePrevention": "CO",
"orderType": "LIMIT",
"side": "BUY",
"lastModifiedTime": 1545718675960,
"orderId": "180eaf73-19ea-4f5e-ae72-c7f5e5f16362",
"instrumentId": "ETH-BTC",
"fee": "0",
"clientOrderId": "",
"orderStatus": "NEW",
"totalExecutedAmount": "0",
"totalExecutedSize": "0",
"postOnly": false,
"stopPrice": "0",
"size": "0.3",
"price": "0.03228",
"createdTime": 1545718675958,
"timeInForce": "GTC"
}
],
"count": 1,
"totalCount": 1
}
Returns an array of open orders; Pagination is supported. Data is returned in descending order of lastModifiedTime. Newest modified orders first, oldest last.
Http request
METHOD: GET
PATH: /api/orders
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | O | If not provided, orders for all symbols are returned |
pageNumber | Integer | O | If not provided, it will use default page number |
pageSize | Integer | O | If not provided, it will use default page size |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
totalCount | Integer | M | |
records | Array of orders | M | |
count | Integer | M |
Record Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
orderId | String | M | |
lastModifiedTime | Long | M | last update time on this order |
instrumentId | String | M | |
orderType | Enum | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M | |
timeInForce | Enum | M | |
createdTime | Long | M | When the order was accepted |
stopPrice | DoubleString | O | |
orderStatus | Enum | M | |
totalExecutedAmount | DoubleString | O | |
totalExecutedSize | DoubleString | O | |
selfTradePrevention | Enum | M | |
clientOrderId | String | O | |
fee | DoubleString | O |
Get All Orders
curl "https://api.xxxx.com/api/allOrders"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/allOrders", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
{
"records": [
{
"selfTradePrevention": "CO",
"orderType": "LIMIT",
"side": "BUY",
"lastModifiedTime": 1545718675960,
"orderId": "180eaf73-19ea-4f5e-ae72-c7f5e5f16362",
"instrumentId": "ETH-BTC",
"fee": "0",
"clientOrderId": "",
"orderStatus": "NEW",
"totalExecutedAmount": "0",
"totalExecutedSize": "0",
"postOnly": false,
"stopPrice": "0",
"size": "0.3",
"price": "0.03328",
"createdTime": 1545718675958,
"timeInForce": "GTC"
},
{
"selfTradePrevention": "CO",
"orderType": "LIMIT",
"side": "SELL",
"lastModifiedTime": 1545719695499,
"orderId": "99b1b4b3-aa0d-493f-b8b4-40d381916686",
"instrumentId": "ETH-BTC",
"fee": "0",
"clientOrderId": "",
"orderStatus": "NEW",
"totalExecutedAmount": "0",
"totalExecutedSize": "0",
"postOnly": false,
"stopPrice": "0",
"size": "0.37",
"price": "0.0332",
"createdTime": 1545719695492,
"timeInForce": "GTC"
}
],
"count": 1,
"totalCount": 1
}
Returns an array of orders; Pagination is supported. Data is returned in descending order of lastModifiedTime. Newest first, oldest last. Cancelled orders in the most recent 2 days are included, the older cancelled orders are not.
Weight: 5
Http request
METHOD: GET
PATH: /api/allOrders
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | O | If not provided, orders for all assets are returned |
orderStatus | Enum | O | If not provided, orders for all status are returned |
pageNumber | Integer | O | If not provided, it will use default page number of 1 |
pageSize | Integer | O | If not provided, it will use default page size of 100 |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
totalCount | Integer | M | |
records | Array of orders | M | |
count | Integer | M |
Record Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
orderId | String | M | |
lastModifiedTime | Long | M | Timestamp of the last update on this order |
instrumentId | String | M | |
orderType | Enum | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M | |
timeInForce | Enum | M | |
createdTime | Long | M | When the order was accepted |
stopPrice | DoubleString | O | |
orderStatus | Enum | M | |
totalExecutedAmount | DoubleString | O | Total executed amount |
totalExecutedSize | DoubleString | O | Total executed size |
selfTradePrevention | Enum | M | Default - CO |
clientOrderId | String | O | |
fee | DoubleString | O |
Fills
curl "https://api.xxxx.com/api/fills"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/fills", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
{
"records": [
{
"side": "SELL",
"size": "0.03",
"orderId": "561b9649-316d-45d2-a704-d595889f0a6a",
"instrumentId": "ETH-BTC",
"price": "0.0325",
"fee": "0.000975",
"createdTime": 1545721629663,
"tradeId": "2"
},
{
"side": "BUY",
"size": "0.3",
"orderId": "3aeca730-0b5a-4727-9277-bac496e3fc22",
"instrumentId": "ETH-BTC",
"price": "0.0317",
"fee": "0.00951",
"createdTime": 1545721629614,
"tradeId": "1"
}
],
"count": 2,
"totalCount": 2
}
Returns an array of fills; Pagination is supported. Data is returned in descending order. Newest first, oldest last.
Weight: 5
Http request
METHOD: GET
PATH: /api/fills
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | O | If not provided, fills for all instruments are returned |
pageNumber | Integer | O | If not provided, it will use default page number of 1 |
pageSize | Integer | O | If not provided, it will use default page size of 100 |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
totalCount | Integer | M | |
records | Array of record | M | |
count | Integer | M |
Record Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
createdTime | Long | M | When the fill occured |
tradeId | String | M | |
orderId | String | M | |
instrumentId | String | M | |
side | Enum | M | |
price | DoubleString | M | |
size | DoubleString | M | |
fee | DoubleString | M |
Withdraw
curl "https://api.xxxx.com/api/withdrawals"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
-X "POST"
-H "Content-Type:application/json"
-d '{"amount":"1.01","address":"2N3EUjhfGFkwCrnoegehrQneskYhFiPJy96","asset":"BTC"}'
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("POST", "https://api.xxxx.com/api/withdrawals", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.setRequestHeader("Content-Type","application/json");
var data = '{"amount":"1.01","address":"2N3EUjhfGFkwCrnoegehrQneskYhFiPJy96","asset":"BTC"}';
xhr.send(data);
}
Sample response:
{
"withdrawId": "94ba30a6-cac5-4270-bb85-e8aa9bed197f",
"timestamp": 1545728118368
}
Http request
METHOD: POST
PATH: /api/withdrawals
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
asset | String | M | |
amount | String | M | |
address | String | M | bankId or cryto address |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
withdrawId | String | M | |
timestamp | Long | M | When the withdraw request was accepted |
Transactions
curl "https://api.xxxx.com/api/transactions"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/transactions", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
{
"records": [
{
"transactionType": "TRADE_FEE",
"amount": "-0.00951",
"balance": "0.7385",
"createdTime": 1545727187909,
"asset": "BTC",
"transactionId": "8d793ebd-d002-4c42-827a-bdfe11668d04",
"referenceId": "ETH-BTC:2"
},
{
"transactionType": "TRADE",
"amount": "0.3",
"balance": "37.67",
"createdTime": 1545727187909,
"asset": "ETH",
"transactionId": "8d793ebd-d002-4c42-827a-bdfe11668d04",
"referenceId": "ETH-BTC:2"
}
],
"count": 2,
"totalCount": 2
}
Weight: 5
Http request
METHOD: GET
PATH: /api/transactions
List all the account transactions that either increases or decreases the account balance and available balance. Pagination is supported.
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
asset | String | O | Return recent transactions for all assets |
transactionType | String | O | |
referenceId | String | O | |
pageNumber | Integer | O | If not provided, it will use default page number of 1 |
pageSize | Integer | O | If not provided, it will use default page size of 100 |
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
transactionId | String | M | |
asset | String | M | |
transactionType | Enum | M | |
amount | DoubleString | M | Amount change triggered by the transaction. |
balance | DoubleString | M | |
available | DoubleString | M | |
createdTime | Long | M | |
referenceId | String | M | Reference id associated with the transaction. TRANSFER(txId) TRADE{tradeId) TRADE_FEE(tradeId) TRANSFER_FEE(txId) |
Balances
curl "https://api.xxxx.com/api/balances"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/balances", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
[
{
"lastModifiedTime": 1545726627568,
"balance": "37.67",
"available": "26.468",
"asset": "ETH"
},
{
"lastModifiedTime": 1545726627570,
"balance": "0",
"available": "0",
"asset": "XRP"
},
{
"lastModifiedTime": 1545726627575,
"balance": "0",
"available": "0",
"asset": "XMR"
},
{
"lastModifiedTime": 1545726627565,
"balance": "0.7385",
"available": "0.673",
"asset": "BTC"
}
]
Http request
METHOD: GET
PATH: /api/balances
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
asset | String | M | |
balance | DoubleString | M | Remaining balance in the asset |
available | DoubleString | M | available balance = balance - outstanding order size - outstanding withdraw request size |
lastModifiedTime | Long | M |
Profit and Loss
curl "https://api.xxxx.com/api/pnls"
-H "API-KEY: e4bdaf100dd50233dbe1b095337f30b6"
-H "API-SIGN: 105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5"
-H "API-TIMESTAMP: 1546065657543"
-H "API-PASSCODE: apiPassphrase1"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/api/pnls", true);
xhr.setRequestHeader("API-KEY","e4bdaf100dd50233dbe1b095337f30b6");
xhr.setRequestHeader("API-SIGN","105f2f99fd52b2c32455f1a4f32534a907005a729e606fc75b3867c94d8203a5");
xhr.setRequestHeader("API-TIMESTAMP","1546065657543");
xhr.setRequestHeader("API-PASSCODE","apiPassphrase1");
xhr.send();
}
Sample response:
[
{
"lastModifiedTime": 1545727761975,
"balance": "37.67",
"previousDayPNL": "39.35",
"costBasis": "4467.66",
"realizedPNL": "634.64",
"asset": "ETH",
"pnlBaseAsset": "USD"
}
]
Http request
METHOD: GET
PATH: /api/pnls
List all the pnls for each holding asset.
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
asset | String | M | |
pnlBaseAsset | String | M | Base asset used to calculate the pnl |
balance | DoubleString | M | Current asset balance |
costBasis | DoubleString | M | Total ost basis in base asset term |
previousDayPNL | DoubleString | M | Previous day pnl in base asset term |
realizedPNL | DoubleString | M | Realized pnl in base asset term |
lastModifiedTime | Long | M |
Websocket Public
Ticker Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var data = '{"type": "subscribe","channel": "ticker","instrumentIds": ["ETH/BTC","XRP/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "ticker",
"instrumentIds": [
"ETH/BTC",
"XRP/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "ticker",
"instrumentIds": [
"ETH/BTC",
"XRP/BTC"
],
"timestamp": 1546414351695
}
//channel
{
"type": "ticker",
"instrumentId": "ETH/BTC",
"timestamp": 1546414339719,
"lastPrice": "0.03811",
"bestBid": "0.03814",
"bestAsk": "0.03815",
"24hHigh": "0.03811",
"24hLow": "0.03662",
"24hVolume": "753.235",
"24hChange": "0.00145",
"sequence": 1
}
Ticker data with 24h market statistics is pushed every second.
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | ticker | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
instrumentIds | Array of instrumentId Strings | M |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribed/Unsubscribed message type |
channel | ticker | M | |
timestamp | Long | M | Request accepted time |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields:
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | ticker | M | |
timestamp | Long | M | Ticker created time |
instrumentId | String | M | e.g. "BTCUSD" |
lastPrice | DoubleString | M | |
bestBid | DoubleString | M | |
bestAsk | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M | |
sequence | Long | M |
Order Book Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var data = '{"type": "subscribe","channel": "orderBook","depth": 25,"instrumentIds": "ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "orderBook",
"depth": 25,
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "orderBook",
"timestamp": 1546414351648,
"depth": 25,
"instrumentId": "ETH/BTC",
"sequence": 1,
"bids": [
[
"0.03816",
"2.165",
1
],
[
"0.03814",
"7.303",
1
],
[
"0.03812",
"0.897",
1
]
],
"asks": [
[
"0.03817",
"7.689",
1
],
[
"0.03818",
"7.344",
1
],
[
"0.03819",
"2.223",
1
]
]
}
//channel
{
"type": "orderBook",
"instrumentId": "ETH/BTC",
"timestamp": 1546414338870,
"sequence": 2,
"bids": [
[
"0.03812",
"0.997",
2
]
],
"asks": [
[
"0.03817",
"0",
0
]
]
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | orderBook | M | |
depth | Integer | O | Default to 25 |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribe/Unsubscribe message type |
channel | orderBook | M | |
timestamp | Long | M | When subscription request was accepted |
depth | Integer | M | |
instrumentId | instrumentId String | M | |
sequence | Long | M | |
bids | Array of [price, size, numOfOrders] | M | Snapshot of bids with the aggregated size for each price level |
asks | Array of [price, size, numOfOrders] | M | Snapshot of asks with the aggregated size for each price level |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | orderBook | M | |
timestamp | Long | M | order book update time |
instrumentId | String | M | |
sequence | Long | M | |
bids | Array of [price, size, numOfOrders] | M | Update of bids with the aggregated size for the updated price level |
asks | Array of [price, size, numOfOrders] | M | Update of asks with the aggregated size for the updated price level |
Full Order Book Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "fullOrderBook", "instrumentIds": ["ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "fullOrderBook",
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "fullOrderBook",
"timestamp": 1546414351648,
"instrumentId": "ETH/BTC",
"sequence": 1,
"bids": [
[
"0.03816",
"2.165",
"6b742a26-5dfb-423f-84de-48182b85c343 "
],
[
"0.03814",
"1.586",
"12a4eb0f-5800-4d74-9305-ef069156e305"
],
[
"0.03814",
"2.457",
"ee63cf9c-cc0b-420c-a30a-c064d0c0c5e3"
],
[
"0.03814",
"3.26",
"c25bc5ef-3ae1-4d8f-a1d1-6da789ef7e5f"
],
[
"0.03812",
"0.897",
"120bd10e-1046-4735-b070-45c35d8e1333"
]
],
"asks": [
[
"0.03817",
"2.059",
"2d4ba2f0-e2fb-4a23-ab6a-0b9e70e20b03"
],
[
"0.03817",
"5.63",
"6ab23323-7270-4c7b-a20e-9abf352365bb"
],
[
"0.03818",
"3.03",
"8ead69cb-b3ef-4cf7-9214-74e5a18225ed"
],
[
"0.03818",
"4.314",
"c877d8fa-b74d-45be-a82e-b731c1e1baaf"
],
[
"0.03819",
"2.223",
"a211216c-98df-4c1a-9fdf-1ffff7e69f99"
]
]
}
//channel
{
"type": "fullOrderBook",
"instrumentId": "ETH/BTC",
"timestamp": 1546414338870,
"sequence": 2,
"bids": [
[
"0.03812",
"0.897",
"120bd10e-1046-4735-b070-45c35d8e1333"
]
],
"asks": [
[
"0.03817",
"0",
"2d4ba2f0-e2fb-4a23-ab6a-0b9e70e20b03"
]
]
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | fullOrderBook | M | |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribe/Unsubscribe message type |
channel | fullOrderBook | M | |
timestamp | Long | M | When the subscription was accepted |
instrumentId | instrumentId String | M | |
sequence | Long | M | |
bids | Array of [price, size, orderId] | M | Snapshot of buy orders |
asks | Array of [price, size, orderId] | M | Snapshot of sell orders |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | fullOrderBook | M | |
timestamp | Long | M | order book update time |
instrumentId | String | M | |
sequence | Long | M | |
bids | Array of [price, size, orderId] | M | Update of buy orders |
asks | Array of [price, size, orderId] | M | Update of sell orders |
Trade Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "trade", "instrumentIds": ["ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample Data
//request
{
"type": "subscribe",
"channel": "trade",
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "trade",
"instrumentIds": [
"ETH/BTC"
],
"timestamp": 1546414344440
}
//channel
{
"type": "trade",
"instrumentId": "ETH/BTC",
"timestamp": 1546414338729,
"tradeId": "480252",
"price": "0.03811",
"size": "0.022",
"side": "SELL",
"sequence": 1
}
trade data is pushed whenever a trade occurs in the system.
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | trade | M | |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | trade | M | |
timestamp | Long | M | When the subscription request was accepted |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | trade | M | |
timestamp | Long | M | Trade time |
instrumentId | String | M | |
tradeId | String | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M | Buy/Sell |
sequence | Long | M |
Charts Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "charts", "instrumentIds": ["ETH/BTC"], "granularity": 900}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "charts",
"instrumentIds": [
"ETH/BTC"
],
"granularity": 900
}
//response
{
"type": "subscribed",
"channel": "charts",
"timestamp": 1546414351696,
"instrumentId": "ETH/BTC",
"granularity": 900,
"records": [
[
1546414200000,
"0.03785",
"0.03811",
"0.03785",
"0.03811",
"70.527",
1546414338753
],
[
1546413300000,
"0.03784",
"0.03787",
"0.03764",
"0.03787",
"33.024"
],
[
1546412400000,
"0.03699",
"0.03781",
"0.03699",
"0.03781",
"180.927"
]
]
}
//channel
{
"type": "charts",
"timestamp": 1546415100061,
"instrumentId": "ETH/BTC",
"granularity": 900,
"update": [
1546414200000,
"0.03785",
"0.03788",
"0.03785",
"0.03816",
"79.250"
]
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | charts | M | |
instrumentIds | Array of instrumentId Strings | M | |
granularity | Integer | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribe/Unsubscribe message type |
channel | charts | M | |
timestamp | Long | M | When the subscription request was accepted |
instrumentId | String | M | |
granularity | Integer | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
records | Array of [startTime,open,close,low,high,volume] | M |
The first charts message will contain the array of historical data entries with the maximum size of 300.
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | charts | M | |
timestamp | Long | M | Chart update time |
instrumentId | String | M | |
granularity | Integer | M | |
update | [startTime,open,close,low,high,volume] | M |
Websocket Private
In order to receive the data on authenticated channels, the websocket session needs to be authenticated first by calling authenticate. Unlike rest requests, the method and path provided by the generated apisign are null.
All requests need to provide the request time in seconds and must be within 5 seconds of the server time or your request will be considered expired and rejected. To change 5 second expiry, user can set expiry to the desired seconds.
Authenticate Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var authentication = '{"type": "authenticate", "timestamp": 1546495887996, "apiKey": "eccd478408970b5359652052b901c22b", "signature": "2367359ea414228956f50613b30f841c47aa0f47c472c484e56ec20cbdcbbcfb", "passcode": "Password1!"}';
ws.send(authentication);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "authenticate",
"timestamp": 1546495887996,
"apiKey": "eccd478408970b5359652052b901c22b",
"signature": "2367359ea414228956f50613b30f841c47aa0f47c472c484e56ec20cbdcbbcfb",
"passcode": "Password1!"
}
//response
{
"type": "authenticated",
"timestamp": 1546495888349
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | authenticate | M | |
timestamp | Long | M | current time in milliseconds from UNIX EPOCH |
apiKey | String | M | |
signature | String | M | Generated by creating a sha256 HMAC using the base64-encoded secret key on the prehash string timestamp + "authenticate" (where + represents string concatenation) and hex-encode the output. |
passcode | String | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
expiry | Integer | O | Seconds for the authenticated channel requests to expire |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | authenticated | M | Subscribe/Unsubscribe message type |
timestamp | Long | M | When authentication is accepted |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Order Update Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var authentication = '{"type": "authenticate", "timestamp": 1546495887996, "apiKey": "eccd478408970b5359652052b901c22b", "signature": "2367359ea414228956f50613b30f841c47aa0f47c472c484e56ec20cbdcbbcfb", "passcode": "Password1!"}';
ws.send(authentication);
var data = '{"channel": "orderUpdate", "type": "subscribe", "instrumentIds": ["ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"channel": "orderUpdate",
"type": "subscribe",
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "orderUpdate",
"timestamp": 1546498910967,
"instrumentIds": [
"ETH/BTC"
],
"openOrders": [
{
"selfTradePrevention": "CO",
"orderType": "LIMIT",
"side": "BUY",
"lastModifiedTime": 1546498739286,
"orderId": "f97800d3-94d3-4176-9be2-0953fbf58aff",
"instrumentId": "ETH/BTC",
"fee": "0",
"clientOrderId": "",
"orderStatus": "NEW",
"totalExecutedAmount": "0",
"totalExecutedSize": "0",
"postOnly": false,
"stopPrice": "0",
"size": "2.56",
"price": "0.03956",
"createdTime": 1546498739285,
"timeInForce": "GTC"
}
]
}
//channel
{
"type": "orderUpdate",
"timestamp": 1546498739285,
"instrumentId": "ETH/BTC",
"orderId": "f97800d3-94d3-4176-9be2-0953fbf58aff",
"orderType": "LIMIT",
"price": "0.03956",
"size": "2.56",
"side": "BUY",
"createdTime": 1546498739285,
"orderStatus": "CANCELLED",
"selfTradePrevention": "CO",
"postLiquidity": true,
"fee": "0",
"totalExecutedAmount": "0",
"cancelReason": "USER_CANCEL",
"sequence": 1
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe | M | Subscribe/Unsubscribe message type |
channel | orderUpdate | M | |
instrumentIds | Array of instrumentId Strings | O | Subscribe/Unsubscribe all instruments by default |
numberOfSnapshotRecords | Integer | O | Max recent number of open orders returned. All open orders will be returned if not specified. |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed | M | Subscribe/Unsubscribe message type |
channel | orderUpdate | M | |
timestamp | Long | M | When the subscription request was accepted |
instrumentIds | Array of instrumentId Strings | O | Subscribed/Unsubscribed for all instruments by default |
openOrders | Array of orders Json Fields | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | orderUpdate | M | |
timestamp | Long | M | Order update time |
orderId | String | M | |
instrumentId | String | M | |
orderType | Enum | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M | |
createdTime | Long | M | |
stopPrice | DoubleString | O | |
orderStatus | Enum | M | |
tradeId | String | O | Available when the current update is a trade |
executedSize | DoubleString | O | Available when the current update is a trade |
executedPrice | DoubleString | O | Available when the current update is a trade |
totalExecutedAmount | DoubleString | O | Total executed amount of all fills in this order |
totalExecutedSize | DoubleString | O | Total executed size of all fills in this order |
postLiquidity | Boolean | O | True - order rest in the book initially |
selfTradePrevention | Enum | M | |
clientOrderId | String | O | |
cancelReason | Enum | O | Provided when order is cancelled |
fee | DoubleString | O | Available when the current update is a trade |
sequence | Long | M |
Account Update Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var authentication = '{"type": "authenticate", "timestamp": 1546495887996, "apiKey": "eccd478408970b5359652052b901c22b", "signature": "2367359ea414228956f50613b30f841c47aa0f47c472c484e56ec20cbdcbbcfb", "passcode": "Password1!"}';
ws.send(authentication);
var data = '{"assets": ["ETH"], "channel": "accountUpdate", "type": "subscribe"}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"assets": [
"ETH"
],
"channel": "accountUpdate",
"type": "subscribe"
}
//response
{
"type": "subscribed",
"timestamp": 1546499784,
"channel": "accountUpdate",
"assets": [
"ETH"
],
"balances": [
{
"lastModifiedTime": 1544680997349,
"balance": "97.59900000",
"available": "97.499",
"asset": "ETH"
}
]
}
//channel
{
"type": "accountUpdate",
"timestamp": 1546499819682,
"updateReason": "NEW_ORDER",
"balances": [
{
"balance": "97.599",
"asset": "ETH",
"availableBalance": "95.199"
}
],
"referenceId": "2906709c-8155-4fa5-ad3c-aa186d481a1a",
"sequence": 1
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe | M | Subscribe/Unsubscribe message type |
channel | accountUpdate | M | |
assets | Array of asset Strings | O | Subscribe for all currencies by default |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed | M | Subscribe/Unsubscribe message type |
channel | accountUpdate | M | |
timestamp | Long | M | When the subscription request is accepted |
assets | Array of asset Strings | O | |
balances | Array of account balances (asset, balance, availableBalance) | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | accountUpdate | M | |
timestamp | Long | M | Account update time |
updateReason | Enum | M | |
balances | Array of account balances (asset, balance, availableBalance) | M | |
referenceId | String | M | NEW_ORDER-orderId; TRADE-tradeId; PENDING_WITHDRAW-withdrawId; TRANSFER-txId |
sequence | Long | M |
PNL Update Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/ws");
ws.onopen = function () {
var authentication = '{"type": "authenticate", "timestamp": 1546495887996, "apiKey": "eccd478408970b5359652052b901c22b", "signature": "2367359ea414228956f50613b30f841c47aa0f47c472c484e56ec20cbdcbbcfb", "passcode": "Password1!"}';
ws.send(authentication);
var data = '{"channel": "pnlUpdate", "type": "subscribe"}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"channel": "pnlUpdate",
"type": "subscribe"
}
//response
{
"type": "subscribed",
"channel": "pnlUpdate",
"timestamp": 1546503078686,
"pnls": [
{
"balance": "0.02140386",
"previousDayPNL": "-1.15",
"costBasis": "84.43",
"realizedPNL": "0.00",
"asset": "BTC",
"pnlBaseAsset": "USD"
},
{
"balance": "99.63100000",
"previousDayPNL": "5092.24",
"costBasis": "10285.78",
"realizedPNL": "84.66",
"asset": "ETH",
"pnlBaseAsset": "USD"
}
]
}
//channel
{
"type": "pnlUpdate",
"timestamp": 1546503078686,
"balance": "99.63100000",
"previousDayPNL": "5092.24",
"costBasis": "10285.78",
"realizedPNL": "84.66",
"asset": "ETH",
"pnlBaseAsset": "USD"
}
We consider all receives as bought events at the receipt time and all sends as sold events at the sent time. As such, the numbers here WILL NOT BE ACCURATE if you have sent digital assets to other platforms.
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe | M | Subscribe/Unsubscribe message type |
channel | pnlUpdate | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed | M | Subscribe/Unsubscribe message type |
channel | pnlUpdate | M | |
timestamp | Long | M | When the subscription request is accepted |
pnls | Array of pnl Json | M | Reference fields in rest GET pnls section |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | pnlUpdate | M | |
timestamp | Long | M | PNL update time |
asset | String | M | |
pnlBaseAsset | String | M | Base asset used to calculate the pnl |
balance | DoubleString | M | Current asset balance |
costBasis | DoubleString | M | Total ost basis in base asset term |
previousDayPNL | DoubleString | M | Previous day pnl in base asset term |
realizedPNL | DoubleString | M | Realized pnl in base asset term |
Consolidated Feed REST
Base endpoint: https://xxx.com/consolidated
Feed Data Sources
curl "https://api.xxxx.com/dataSources"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/dataSources", true);
xhr.send();
}
Sample response:
[
{
"instrumentId": "ETH/BTC",
"dataSources": [
"COINBASE_PRO",
"BITSTAMP",
"BITFINEX",
"GEMINI"
]
}
]
Get data sources of consolidated feed
Http request
METHOD: GET
PATH: /api/dataSources
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | O |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. BTCUSD |
dataSources | Array of dataSource | M | e.g. [COINBASE_PRO, BITSTAMP, BITFINEX] |
Feed Ticker
curl "https://api.xxxx.com/ticker?instrumentId=ETH/BTC&dataSource=CONSOLIDATED"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/ticker?instrumentId=ETH/BTC&dataSource=CONSOLIDATED", true);
xhr.send();
}
Sample response:
{
"24hLow": "0.0314",
"24hVolume": "33113.85823278",
"lastModifiedTime": 1545996511335,
"instrumentId": "ETH/BTC",
"24hHigh": "0.03327",
"24hChange": "-0.00082",
"dataSource": "CONSOLIDATED",
"lastPrice": "0.03245"
}
Http request
METHOD: GET
PATH: /api/ticker
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. "ETHBTC" |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. "ETHBTC" |
dataSource | Enum | M | |
lastModifiedTime | Long | M | |
lastPrice | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M |
Feed All Tickers
curl "https://api.xxxx.com/allTickers?dataSource=CONSOLIDATED"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/allTickers?dataSource=CONSOLIDATED", true);
xhr.send();
}
Sample response:
[
{
"24hLow": "0.0314",
"24hVolume": "33113.85823278",
"lastModifiedTime": 1545996511335,
"instrumentId": "ETH/BTC",
"24hHigh": "0.03327",
"24hChange": "-0.00082",
"dataSource": "CONSOLIDATED",
"lastPrice": "0.03245"
}
]
Http request
METHOD: GET
PATH: /api/allTickers
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
dataSource | Enum | M | e.g. "CONSOLIDATED" |
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | e.g. "ETHBTC" |
dataSource | Enum | M | |
lastModifiedTime | Long | M | |
lastPrice | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M |
Feed Order Book
curl "https://api.xxxx.com/orderbook?instrumentId=ETH/BTC&bookLevel=1&dataSource=CONSOLIDATED"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/orderbook?instrumentId=ETH/BTC&bookLevel=1&dataSource=CONSOLIDATED", true);
xhr.send();
}
Sample response:
{
"dataSource": "CONSOLIDATED",
"sequence": "5",
"lastModifiedTime": 1545734172781,
"bookLevel": 1,
"instrumentId": "ETH/BTC",
"asks": [
{
"size": "0.0752",
"price": "59.0",
"numOfOrders": 0
},
{
"size": "1000.0",
"price": "50.0",
"numOfOrders": 0
},
{
"size": "0.01",
"price": "39.59",
"numOfOrders": 0
}
],
"bids": [
{
"size": "100.49862944",
"price": "0.03236",
"numOfOrders": 0
},
{
"size": "1.232",
"price": "0.03235",
"numOfOrders": 0
},
{
"size": "14.22706801",
"price": "0.03234",
"numOfOrders": 0
}
]
}
Weight: 5
Http request
METHOD: GET
PATH: /api/orderbook
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
level | Integer | M | 1 - top bid and ask; 2 - order book; |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
lastModifiedTime | Long | M | |
level | Integer | M | 1/2 |
sequence | Long | M | |
bids | Array of [price, size, numOfOrders/orderId] | M | Level 1 - This is one sized array;Level 2 - The aggregated size for each price level is returned with numOfOrders count for the price;Level |
asks | Array of [price, size, numOfOrders/orderId] | M | Level 1 - This is one sized array;Level 2 - The aggregated size for each price level is returned with numOfOrders count for the price;Level |
Feed Trades
curl "https://api.xxxx.com/trades?instrumentId=ETH/USD&dataSource=COINBASE_PRO"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/trades?instrumentId=ETH/USD&dataSource=COINBASE_PRO", true);
xhr.send();
}
Sample response:
[
{
"side": "SELL",
"size": "45.12434133",
"instrumentId": "ETH/BTC",
"price": "0.03241",
"createdTime": 1545998177713,
"dataSource": "COINBASE_PRO"
},
{
"side": "SELL",
"size": "0.0179406",
"instrumentId": "ETH/BTC",
"price": "0.03241",
"createdTime": 1545998177713,
"dataSource": "COINBASE_PRO"
},
{
"side": "SELL",
"size": "0.0179406",
"instrumentId": "ETH/BTC",
"price": "0.03241",
"createdTime": 1545998177713,
"dataSource": "COINBASE_PRO"
}
]
Returns most recent trades in an array.
Http request
METHOD: GET
PATH: /api/trades
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
Success Response Body Array Json Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
createdTime | Long | M | |
tradeId | String | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M |
Feed Charts
curl "https://api.xxxx.com/charts?instrumentId=ETH/BTC&dataSource=COINBASE_PRO&startTime=1545998077713&endTime=1545998277713&granularity=60"
function request() {
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
return this.responseText;
}
});
xhr.open("GET", "https://api.xxxx.com/charts?instrumentId=ETH/BTC&dataSource=COINBASE_PRO&startTime=1545998077713&endTime=1545998277713&granularity=60", true);
xhr.send();
}
Sample response:
[
{
"volume": "1.0567541",
"high": "0.03244",
"low": "0.03242",
"openPrice": "0.03242",
"startTime": 1545998220000,
"endTime": 1545998330000,
"lastModifiedTime": 1545998230000,
"closePrice": "0.03244",
"dataSource": "COINBASE_PRO"
},
{
"volume": "45.22106593",
"high": "0.03241",
"low": "0.03241",
"openPrice": "0.03241",
"startTime": 1545998160000,
"endTime": 1545998330000,
"lastModifiedTime": 1545998230000,
"closePrice": "0.03241",
"dataSource": "COINBASE_PRO"
},
{
"volume": "0.2743248",
"high": "0.0324",
"low": "0.0324",
"openPrice": "0.0324",
"startTime": 1545998100000,
"endTime": 1545998330000,
"lastModifiedTime": 1545998230000,
"closePrice": "0.0324",
"dataSource": "COINBASE_PRO"
}
]
It returns an array of data point stats.
Http request
METHOD: GET
PATH: /api/charts
Request Parameters
Name | Type(value) | Mandatory | Description |
---|---|---|---|
instrumentId | String | M | |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
startTime | Long | M | Seconds since Unix Epoch |
endTime | Long | O | Seconds since Unix Epoch |
granularity | Integer | M | In seconds; 60/300/900/3600/21600/86400;The combination of startTime, endTime and granularity determines how many data points obtained. The maximum supported number of data points is xxx |
Success Response Body Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
lastModifiedTime | Long | O | |
dataSource | Enum | M | e.g. "CONSOLIDATED" |
startTime | Long | M | |
openPrice | String | M | |
closePrice | String | M | |
low | String | M | |
high | String | M | |
volume | String | M |
Base endpoint: wss://xxx.com/consolidated
Consolidated Feed Websocket
Feed Data Sources Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/cfs");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "dataSource", "instrumentIds": ["ETH/BTC", "XLM/BTC", "XMR/BTC", "XRP/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "dataSource",
"instrumentIds": [
"ETH/BTC",
"XLM/BTC",
"XMR/BTC",
"XRP/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "dataSource",
"instrumentId": "ETH/BTC",
"dataSources": [
"BITSTAMP",
"BITFINEX",
"GEMINI",
"COINBASE_PRO"
],
"timestamp": 1546506477512
}
//channel
{
"instrumentId": "ETH/BTC",
"type": "dataSource",
"dataSource": [
"BITSTAMP",
"BITFINEX",
"COINBASE_PRO"
],
"timestamp": 1546509059461197
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | dataSource | M | |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | dataSource | M | |
instrumentId | instrumentId String | M | |
dataSources | Array of Enum | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields:
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | dataSource | M | |
instrumentId | String | M | e.g. "BTC/USD" |
dataSources | Array of Enum | M | |
timestamp | Long | M | data source update time |
Feed Ticker Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/cfs");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "ticker", "instrumentIds": ["ETH/BTC", "XLM/BTC", "XMR/BTC", "XRP/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "ticker",
"instrumentIds": [
"ETH/BTC",
"XLM/BTC",
"XMR/BTC",
"XRP/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "ticker",
"instrumentIds": [
"ETH/BTC",
"XLM/BTC",
"XMR/BTC",
"XRP/BTC"
],
"timestamp": 1546508497272
}
//channel
{
"type": "ticker",
"dataSource": "BITSTAMP",
"timestamp": 1546508495096,
"instrumentId": "ETH/BTC",
"lastPrice": "0.03872964",
"24hHigh": "0.04",
"24hLow": "0.0382027",
"24hVolume": "4953.03785251",
"24hChange": "0.00024413"
}
Ticker data with 24h market statistics is pushed every 5 seconds
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | ticker | M | |
dataSource | Enum | O | Subscribe/Unsubscribe all data sources by default including "CONSOLIDATED" ticker price |
userMessageId | Integer | O | Unique message id for this websocket session |
instrumentIds | Array of instrumentId Strings | M |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribed/Unsubscribed message type |
channel | ticker | M | |
dataSource | Enum | M | |
timestamp | Long | M | Request accepted time |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields:
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | ticker | M | |
dataSource | Enum | M | |
timestamp | Long | M | Ticker created time |
instrumentId | String | M | e.g. "BTCUSD" |
lastPrice | DoubleString | M | |
24hHigh | DoubleString | M | |
24hLow | DoubleString | M | |
24hVolume | DoubleString | M | |
24hChange | DoubleString | M |
Feed Order Book Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/cfs");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "orderBook", "depth": 50, "instrumentIds": ["ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "orderBook",
"depth": 50,
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "orderBook",
"timestamp": 1546511253719,
"dataSource": "COINBASE_PRO",
"depth": 50,
"instrumentId": "ETH/BTC",
"bids": [
[
"0.03898",
"3.44469471"
],
[
"0.03897",
"0.1515"
],
[
"0.03896",
"11.82334269"
]
]
}
//channel
{
"type": "orderBook",
"instrumentId": "ETH/BTC",
"timestamp": 1546511328,
"dataSource": "GEMINI",
"bids": [
[
"0.03801",
"50"
]
],
"asks": []
}
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | orderBook | M | |
dataSource | Enum | O | Subscribe/Unsubscribe all exchange data sources by default |
depth | Integer | O | Default to 25 |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribed | M | Subscribe/Unsubscribe message type |
channel | orderBook | M | |
dataSource | Enum | M | |
timestamp | Long | M | When subscription request was accepted |
depth | Integer | M | |
instrumentId | instrumentId String | M | |
bids | Array of [price, size] | M | Snapshot of bids with the aggregated size for each price level |
asks | Array of [price, size] | M | Snapshot of asks with the aggregated size for each price level |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | orderBook | M | |
timestamp | Long | M | order book update time |
instrumentId | String | M | |
dataSource | Enum | M | |
bids | Array of [price, size] | M | Update of bids with the aggregated size for the updated price level |
asks | Array of [price, size] | M | Update of asks with the aggregated size for the updated price level |
Feed Trade Channel
function WebSocketCall() {
var ws = new WebSocket("wss://ws-api.xxxx.com/cfs");
ws.onopen = function () {
var data = '{"type": "subscribe", "channel": "trade", "instrumentIds": ["ETH/BTC"]}';
ws.send(data);
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
};
}
Sample data:
//request
{
"type": "subscribe",
"channel": "trade",
"instrumentIds": [
"ETH/BTC"
]
}
//response
{
"type": "subscribed",
"channel": "trade",
"instrumentIds": [
"ETH/BTC"
],
"timestamp": 1546514515204
}
//channel
{
"type": "trade",
"instrumentId": "ETH/BTC",
"timestamp": 1546514515175,
"dataSource": "COINBASE_PRO",
"price": "0.03853",
"size": "0.01",
"side": "SELL"
}
trade data is pushed whenever a trade occurs in the system.
Request Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribe/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | trade | M | |
dataSource | Enum | O | Subscribe/Unsubscribe all exchange data sources by default |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | O | Unique message id for this websocket session |
Response Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | subscribed/unsubscribe | M | Subscribe/Unsubscribe message type |
channel | trade | M | |
dataSource | Enum | M | |
timestamp | Long | M | When the subscription request was accepted |
instrumentIds | Array of instrumentId Strings | M | |
userMessageId | Integer | (M) | Mandatory if userMessageId is provided in the user request |
Channel Fields
Name | Type(value) | Mandatory | Description |
---|---|---|---|
type | trade | M | |
timestamp | Long | M | Trade time |
instrumentId | String | M | |
dataSource | Enum | M | |
tradeId | String | M | |
price | DoubleString | M | |
size | DoubleString | M | |
side | Enum | M | Buy/Sell |
Enums
orderStatus
Order Status | Description |
---|---|
PENDING_NEW | New order has been accepted |
NEW | New order has been booked |
PARTIAL_FILLED | Order is partially filled |
FILLED | Order is fully filled |
PENDING_CANCEL | Order cancel request has been accepted |
CANCELLED | Order has been cancelled and removed from book |
timeInForce
Time in Force | Description |
---|---|
GTC | Good till cancelled orders remain in the book until cancelled or filled. |
IOC | Immediate or cancel orders must be executed instantly and any unfilled parts of the order are cancelled. |
FOK | Fill or kill orders are rejected if the entire size can not be matched. |
side
Side | Description |
---|---|
BUY | Buy order indicator |
SELL | Sell order indicator |
selfTradePrevention
Self Trade Prevention | Description |
---|---|
CO | Cancel older order in the book |
CN | Cancel new order |
CB | Cancel both orders |
orderType
Order Type | Description |
---|---|
LIMIT | Limit orders require specifying a price and size |
MARKET | Market orders provide no pricing guarantees. They execute immediatly and no part of the market order will go on the orer book. |
STOP_LOSS (TBA) | A market order is placed when the last price moves to the value at or below the stop price. The trade may happen at the worse price than stop price. |
STOP_LOSS_LIMIT (TBA) | A limit order is placed when the last price moves to the value at or below the stop price. |
STOP_ENTRY (TBA) | A market order is placed when the last price moves to the value at or above the stop price. The trade may happen at the worse price than stop price. |
STOP_ENTRY_LIMIT (TBA) | A limit order is placed when the last price moves to the value at or above the stop price. |
instrumentType
Instrument Type | Description |
---|---|
SPOT | |
FUTURES (TBA) |
cancelReason
Order Cancel Reason | Description |
---|---|
USER_CANCEL | The order is cancelled by user. |
NO_LIQUIDITY | Market order or IOC order cancelled remaining by system. |
SELF_TRADE | The order is cancelled due to self trade prevention. |
POST_ONLY | The post only order is taking liquidity, cancelled by system. |
INSUFFICIENT_LIQUIDITY | The FOK order cannot fully trade, cancelled by system. |
TOTAL_EXECUTED_SIZE_MORE_THAN_MAX_SIZE | The MARKET BUY order executed more than maxOrderSize, cancelled by system. |
INSUFFICIENT_QUOTE_AMOUNT | The MARKET BUY order quoteAmount too small, cancelled by system. |
INACTIVE_INSTRUMENT | The instrument status is INACTIVE, cancelled by system. |
EXCEED_BALANCE | The MARKET order exceed balance, cancelled by system. |
updateReason
Account Update Reason | Description |
---|---|
NEW_ORDER | The account update that is triggered by new order. |
PENDING_WITHDRAW | The account update that is triggered by pending withdraw. |
TRADE | The account update that is triggered by trade. |
TRANSFER | The account update that is triggered by completed transfer. |
transactionType
Transaction Type | Description |
---|---|
TRADE | The account transaction entry triggered by TRADE. |
TRANSFER | The account transaction entry triggered by TRANSFER. |
TRADE_FEE | The account transaction entry triggered by TRADE_FEE. |
TRANSFER_FEE | The account transaction entry triggered by TRANSFER_FEE. |
apikeyAuthority
Apikey Authority | Description |
---|---|
ACCOUNT_VIEW | The authority of apikey for accounts read related url access. |
TRADE_VIEW | The authority of apikey for trades read related url access. |
TRADE | The authority of apikey for trades related url access. |
WITHDRAW | The authority of apikey for withdraw url access. |
twoFactorAuthorization
Two Factor Authorization | Description |
---|---|
LOGIN | The login url that need two factor code authentication |
UPDATE_PROFILE | The update profile url that need two factor code authentication |
TRADE | The trade realted urls that need two factor code authentication |
TRANSFER | The transfer related urls that need two factor code authentication |
loggedOutReason
Logged Out Reason | Description |
---|---|
NORMAL_LOGOUT | User initiates the logout |
NEW_SESSION_INIT | User starts a new login session |
USER_DISABLED | User is disabled |
SYSTEM_LOGOUT | System logs out the user |
RESET_PASSWORD | User is logged out due to password reset |
withdrawalStatus
Withdrawal Status | Description |
---|---|
PENDING | The initial withdrawal request status |
IN_PROGRESS | Withdrawal request is being processed |
UNCONFIRMED | Coin withdrawal request has been broadcast to network, but is not confirmed |
COMPLETED | Coin withdrawal request has been confirmed |
CANCELLED | Withdrawal request has been cancelled |
dataSource
Data Source | Description |
---|---|
CONSOLIDATED | Consolidated data |
COINBASE_PRO | Coinbase pro exchange data |
BITSTAMP | Bitstamp exchange data |
BITFINEX | Bitfinex exchange data |
GEMINI | Gemini exchange data |
KRAKEN | Kraken exchange data |
Error Codes
Error Code | Description |
---|---|
EXCEED_BALANCE | Insufficient balance for the new order. |
ALREADY_DONE | The order is already cancelled or fully filled. |
ALREADY_PENDING_CANCEL | The order is already in pending cancel state. |
INVALID_INSTRUMENT | The instrumentId is invalid or has been disabled |
SIZE_LESS_THAN_MIN_SIZE | The order size is less than the minOrderSize of the instrument. |
SIZE_MORE_THAN_MAX_SIZE | The order size is more than the maxOrderSize of the instrument. |
SIZE_NOT_DIVISIBLE_BY_LOT_SIZE | The order size is either too high or too low and not in the multiples of the instrument. |
PRICE_NOT_DIVISIBLE_BY_TICK_SIZE | The order price is not divisible by the tickSize of the instrument. |
INVALID_ORDER_SIDE | The side is invalid. |
INVALID_ORDER_STATUS | The orderStatus is invalid. |
UNIQUE_ORDER_ID_REQUIRED | Neither orderId nor clientOrderId is provided. |
INVALID_INSTRUMENT_STATUS | Request is not allowed in current instrument status. |
QUOTE_AMOUNT_REQUIRED | The orderType is MARKET and side is BUY but quoteAmount is not provided. |
SIZE_REQUIRED | The orderType is MARKET and side is SELL but size is not provided. |
PRICE_LESS_THAN_MIN_PRICE | The order price is less than the minOrderPrice of the instrument. |
PRICE_MORE_THAN_MAX_PRICE | The order price is more than the maxOrderPrice of the instrument. |
PENDING_BALANCE_ADJUSTMENT | Pending balance adjustment from previous order or account action. |
ORDER_SERVICE_NOT_ENABLED | The order service is not enabled. |
SIZE_OR_QUOTE_AMOUNT_REQUIRED | The orderType is MARKET and neither size nor quoteAmount is provided. |
API_BAD_REQUEST, | Bad request that contains either invalid fields or invalid field values |
INTERNAL_SERVER_ERROR, | Internal server error. |
API_CALL_UNAUTHORIZED, | The api call is not authenticated. |
TWO_FACTOR_UNAUTHORIZED, | Need two factor authentication. |
INVALID_EMAIL_FORMAT, | The email provided by the user is valid. |
INVALID_USERNAME_FORMAT, | The user name provided by the user is invalid. |
INVALID_REGISTRATION_CONFIRMATION_CODE, | User invalid confirm code. |
INVALID_OLD_PASSWORD, | The password provided by user to reset password is invalid. |
BAD_PASSWORD, | Password format dosen't meet the requirement. |
EMAIL_IN_USE, | The email is registered by other user. |
USERNAME_IN_USE, | The username is registered by other user. |
USER_REGISTRATION_UNCONFIRMED, | The user has registered but not confirmed. |
USER_REGISTRATION_HAS_BEEN_CONFIRMED, | The user has been confirmed already. |
USER_DISABLED, | The user is disabled. |
USER_AUTH_BAD_CREDENTIALS, | The credentials provided by user is invalid. |
PASSWORD_SAME_TO_PREVIOUS, | Cannot set the password same to previous. |
USER_NOT_EXIST, | User not exist. |
TWO_FACTOR_AUTH_NOT_ACTIVATED, | Must activate two factor auth to proceed two factor actions. |
TWO_FACTOR_AUTH_HAS_ACTIVATED, | Two factor auth has been activated, please don't do it again. |
INVALID_USERACCOUNT_NAME_FORMAT, | The user account name provided by user is invalid. |
USERACCOUNT_NAME_IN_USE, | The user account name has been taken. |
USER_MAIN_ACCOUNT_DELETE_NOT_ALLOWED, | Cannot delete the user main account. |
USER_MAIN_ACCOUNT_HAS_EXISTED, | Cannot create user main account cause the user already has one. |
USERACCOUNT_DELETE_NOT_ALLOW, | User account deletion is not allowed. |
USERACCOUNT_DISABLED, | The user account is disabled. |
USERACCOUNT_NOT_EXIST, | Can't find the user account with the provided credentials. |
APIKEY_NOT_EXIST, | Cannot find the apikey with the provided credentials. |
APIKEY_DISABLED, | The apikey is disabled. |
BAD_PASSCODE, | The apikey passcode is invalid. |
INVALID_AUTHORITIES | The authorities is invalid. |
INVALID_TWO_FACTOR_AUTHORIZATION | Invalid two factor authentication. |
INVALID_INSTRUMENT_ID | The instrument id is invalid. |
INSTRUMENT_INACTIVED | The instrument id in inactivated. |
INVALID_TWO_FACTOR_CODE | Invalid two factor authentication code. |
INVALID_RESET_PASSWORD_LINK | The reset password link is expired or invalid. |
EXCEED_MAX_WITHDRAWAL_LIMIT_PER_DAY | Exceed max withdrawal limit per day. |
EXCEED_MAX_WITHDRAWAL_LIMIT | Exceed max withdrawal limit. |
WITHDRAW_AMOUNT_TOO_SMALL | Less than min withdraw limit. |
WITHDRAW_ID_NOT_EXIST | Cancel withdraw request withdraw id not exist. |
WITHDRAW_ALREADY_PROCESSED | Cancel withdraw request but withdraw already not pending status. |
INVALID_ASSET | Invalid asset. |
UNSUPPORTED_DATA_SOURCE | Unsupported data source |
USER_IS_READ_ONLY | User is read only |