Introduction
Welcome
Welcome to the Crypto.com Exchange API v1 (OTC 2.0 REST/WS API) reference documentation.
Where applicable, all API calls come with detailed information on both the request and response parameters, all in a simple JSON format, as well as sample requests and code snippets in JavaScript, Python, C#, and Java which can be viewed on the right.
Change Logs
- 2024-02-07 - First publish.
- 2025-06-17 - Updated description of fields and
Quote Request Reason Code
section; Removed LP-specified (lp_name
,lp_name_list
) fields from all requests and responses; Added response fields (reason
,quote_id
,notional
,type
,response_time_ns
,update_time_ns
,expire_time_ns
); Updated request-quote API with new parameters (firm_quote
,quote_ttl
) and made side field required; Updated quote query APIs (get-open-quotes & get-quote-history) to addbid
andask
to leg_list response, removedside
andprice
in leg_list response.
Common API Reference
Some of the APIs for REST and Websockets are shared, and follow the same request format and response.
The Applies To
section under each API allows you to see which platform supports the API.
Naming Conventions
All methods and URLs in dash-case
All parameters in snake_case
Enums in full uppercase and snake_case
Generating the API Key
Before sending any requests, you'll need to generate a new API key.
This can be done in the Exchange website under User Center
- API
.
After generating the key, there are two things you need to carefully note down:
- API Key
- Secret Key
API Key and Secret are randomly generated by the system and can not be modified. Default settings will be set to "Can Read" only, and you have the option of adding or removing certain permissions for your API Key via Web UI.
You can optionally specify a whitelist of IP addresses when generating the API Key.
If specified, the API can only be used from the whitelisted IP addresses.
REST API Root Endpoint
UAT Sandbox
REST API
https://uat-api.3ona.co/exchange/v1/{method}
Production
REST API
https://api.crypto.com/exchange/v1/{method}
Websocket Root Endpoints
The Websocket is available across two servers -- the User API Websocket (for authenticated requests and subscriptions), and Market Data Websocket:
UAT Sandbox
Websocket (User API and Subscriptions)
wss://uat-stream.3ona.co/exchange/v1/user
Websocket (Market Data Subscriptions)
wss://uat-stream.3ona.co/exchange/v1/market
Production
Websocket (User API and Subscriptions)
wss://stream.crypto.com/exchange/v1/user
Websocket (Market Data Subscriptions)
wss://stream.crypto.com/exchange/v1/market
Rate Limits
---------------------------------------------------TBC--------------------------------------------------------------------
REST API
Method | Limit |
---|---|
get-open-quote-requests | 1 requests per second |
get-open-quotes | 1 requests per second |
get-quote-request-history | 1 requests per second |
get-quote-history | 1 requests per second |
get-open-deals | 1 requests per second |
get-deal-history | 1 requests per second |
get-settle-later-limit | 1 requests per second |
get-unsettled-amounts | 1 requests per second |
Websocket
Websocket | Limit |
---|---|
request-quote | 2 requests per second |
request-deal | 2 requests per second |
respond-quote | 20-30 requests per second |
We recommend adding a 1-second sleep after establishing the websocket connection, and before requests are sent.
This will avoid occurrences of rate-limit (`TOO_MANY_REQUESTS`) errors, as the websocket rate limits are pro-rated based on the calendar-second that the websocket connection was opened.
Request Format
The following information applies to both REST API and websockets commands:
Name | Type | Required | Description |
---|---|---|---|
id | long | Y | Request Identifier Range: 0 to 9,223,372,036,854,775,807 Response message will contain the same id |
method | string | Y | The method to be invoked |
params | object | N | Parameters for the methods |
api_key | string | Depends | API key. See Digital Signature section |
sig | string | Depends | Digital signature. See Digital Signature section |
nonce | long | Y | Current timestamp (milliseconds since the Unix epoch) |
Digital Signature
const crypto = require("crypto-js");
const signRequest = (request_body, api_key, secret) => {
const { id, method, params, nonce } = request_body;
function isObject(obj) { return obj !== undefined && obj !== null && obj.constructor == Object; }
function isArray(obj) { return obj !== undefined && obj !== null && obj.constructor == Array; }
function arrayToString(obj) { return obj.reduce((a,b) => { return a + (isObject(b) ? objectToString(b) : (isArray(b) ? arrayToString(b) : b)); }, ""); }
function objectToString(obj) { return (obj == null ? "" : Object.keys(obj).sort().reduce((a, b) => { return a + b + (isArray(obj[b]) ? arrayToString(obj[b]) : (isObject(obj[b]) ? objectToString(obj[b]) : obj[b])); }, "")); }
const paramsString = objectToString(params);
console.log(paramsString);
const sigPayload = method + id + api_key + paramsString + nonce;
request_body.sig = crypto.HmacSHA256(sigPayload, secret).toString(crypto.enc.Hex);
};
const apiKey = "token"; /* User API Key */
const apiSecret = "secretKey"; /* User API Secret */
let request = {
id: 11,
method: "private/get-order-detail",
api_key: API_KEY,
params: {
order_id: 53287421324
},
nonce: 1587846358253,
};
const requestBody = JSON.stringify(signRequest(request, apiKey, apiSecret)));
import hmac
import hashlib
import time
API_KEY = "API_KEY"
SECRET_KEY = "SECRET_KEY"
req = {
"id": 14,
"method": "private/create-order-list",
"api_key": API_KEY,
"params": {
"contingency_type": "LIST",
"order_list": [
{
"instrument_name": "ONE_USDT",
"side": "BUY",
"type": "LIMIT",
"price": "0.24",
"quantity": "1.0"
},
{
"instrument_name": "ONE_USDT",
"side": "BUY",
"type": "STOP_LIMIT",
"price": "0.27",
"quantity": "1.0",
"trigger_price": "0.26"
}
]
},
"nonce": int(time.time() * 1000)
}
# First ensure the params are alphabetically sorted by key
param_str = ""
MAX_LEVEL = 3
def params_to_str(obj, level):
if level >= MAX_LEVEL:
return str(obj)
return_str = ""
for key in sorted(obj):
return_str += key
if obj[key] is None:
return_str += 'null'
elif isinstance(obj[key], list):
for subObj in obj[key]:
return_str += params_to_str(subObj, level + 1)
else:
return_str += str(obj[key])
return return_str
if "params" in req:
param_str = params_to_str(req['params'], 0)
payload_str = req['method'] + str(req['id']) + req['api_key'] + param_str + str(req['nonce'])
req['sig'] = hmac.new(
bytes(str(SECRET_KEY), 'utf-8'),
msg=bytes(payload_str, 'utf-8'),
digestmod=hashlib.sha256
).hexdigest()
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Net.WebSockets;
private const string API_KEY = "YOUR_API_KEY";
private const string API_SECRET = "YOUR_API_SECRET";
private static string GetSign (Dictionary Request)
{
Dictionary Params = Request.Params;
// Ensure the params are alphabetically sorted by key
// When params contains List value, please refer to the other language's example code for the correct implementation of ParamString
string ParamString = string.Join("", Params.Keys.OrderBy(key => key).Select(key => key + Params[key]));
string SigPayload = Request.method + Request.id + API_KEY + ParamString + Request.nonce;
var hash = new HMACSHA256(API_SECRET);
var ComputedHash = hash.ComputeHash(SigPayload);
return ToHex(ComputedHash, false);
}
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ApiRequestJson {
private Long id;
private String method;
private Map<String, Object> params;
private String sig;
@JsonProperty("api_key")
private String apiKey;
private Long nonce;
}
//------------
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Hex;
public class SigningUtil {
private static final String HMAC_SHA256 = "HmacSHA256";
private static final int MAX_LEVEL = 3;
public static boolean verifySignature(ApiRequestJson apiRequestJson, String secret) {
try {
return genSignature(apiRequestJson, secret).equalsIgnoreCase(apiRequestJson.getSig());
} catch (Exception e) {
return false;
}
}
@SuppressWarnings("unchecked")
public static String getParamString(final Object paramObject) {
StringBuilder sb = new StringBuilder();
appendParamString(sb, paramObject, 0);
return sb.toString();
}
@SuppressWarnings("unchecked")
private static void appendParamString(final StringBuilder paramsStringBuilder, final Object paramObject, final int level) {
if (level >= MAX_LEVEL) {
paramsStringBuilder.append(paramObject.toString());
return;
}
if (paramObject instanceof Map) {
TreeMap<String, Object> params = new TreeMap<>((Map) paramObject);
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (entry.getValue() instanceof Double) {
paramsStringBuilder
.append(entry.getKey())
.append((new BigDecimal(entry.getValue().toString()))
.stripTrailingZeros()
.toPlainString());
} else if (entry.getValue() instanceof List || entry.getValue() instanceof Map) {
paramsStringBuilder
.append(entry.getKey());
appendParamString(paramsStringBuilder, entry.getValue(), level + 1);
} else {
paramsStringBuilder
.append(entry.getKey())
.append(entry.getValue());
}
}
} else if (paramObject instanceof List) {
List list = (List) paramObject;
for (Object o : list) {
appendParamString(paramsStringBuilder, o, level + 1);
}
} else {
paramsStringBuilder.append(paramObject.toString());
}
}
public static String genSignature(ApiRequestJson apiRequestJson, String secret)
throws NoSuchAlgorithmException, InvalidKeyException {
final byte[] byteKey = secret.getBytes(StandardCharsets.UTF_8);
Mac mac = Mac.getInstance(HMAC_SHA256);
SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA256);
mac.init(keySpec);
String paramsString = "";
if (apiRequestJson.getParams() != null) {
paramsString += getParamString(apiRequestJson.getParams());
}
String sigPayload =
apiRequestJson.getMethod()
+ apiRequestJson.getId()
+ apiRequestJson.getApiKey()
+ paramsString
+ (apiRequestJson.getNonce() == null ? "" : apiRequestJson.getNonce());
byte[] macData = mac.doFinal(sigPayload.getBytes(StandardCharsets.UTF_8));
return Hex.encodeHexString(macData);
}
public static ApiRequestJson sign(ApiRequestJson apiRequestJson, String secret)
throws InvalidKeyException, NoSuchAlgorithmException {
apiRequestJson.setSig(genSignature(apiRequestJson, secret));
return apiRequestJson;
}
public static void main(String[] argv) throws InvalidKeyException, NoSuchAlgorithmException {
ApiRequestJson apiRequestJson = ApiRequestJson.builder()
.id(11L)
.apiKey("token")
.method("public/auth")
.nonce(1589594102779L)
.build();
System.out.println(genSignature(apiRequestJson, "secretKey"));
System.out.println(sign(apiRequestJson, "secretKey"));
}
}
For REST API, only the private methods require a Digital Signature (as "sig") and API key (as "api_key") to be passed in. These private endpoints are only accessible by authenticated users.
For Websocket (User API), the public/auth
command has to be invoked ONCE per session, with the Digital Signature (as "sig") and API key (as "api_key") as part of the request. Once authenticated, you will gain access to user-specific commands, and no longer need to use the pass in the Digital Signature and API key anymore for the duration of the session.
The authentication is based on the pairing of the API Key, along with the HMAC-SHA256 hash of the request parameters using the API Secret as the cryptographic key.
The algorithm for generating the HMAC-SHA256 signature is as follows:
If "params" exist in the request, sort the request parameter keys in ascending order.
Combine all the ordered parameter keys as
key
+value
(no spaces, no delimiters). Let's call this theparameter string
Next, do the following:
method
+id
+api_key
+parameter string
+nonce
Use HMAC-SHA256 to hash the above using the API Secret as the cryptographic key
Encode the output as a hex string -- this is your Digital Signature
Request Format
All prices must be strings, and must be wrapped in double quotes.
Response Format
Name | Type | Description |
---|---|---|
id | long | Original request identifier |
method | string | Method invoked |
result | object | Result object |
code | int | 0 for success, see below for full list |
message | string | (optional) For server or error messages |
original | string | (optional) Original request as a string, for error cases |
Response and Reason Codes
Quote Request Reason Code
Code | Reason | Description |
---|---|---|
40003 | INVALID_REQUEST | request-quote missing channel subscription request-quote contains invalid value |
40004 | MISSING_OR_INVALID_ARGUMENT | request-quote missing required param or contains invalid param(s) |
110002 | OTC_IS_SUSPENDED | request-quote flow is suspended in OTC |
401 | ACCOUNT_DOES_NOT_EXIST | Account ID not found in OTC |
420 | USER_NOT_FOUND | User ID not found in OTC |
110045 | EXCEEDS_MAX_OPEN_QUOTE_REQUESTS | User exceeds maximum number of open quote requests |
110019 | EXTERNAL_ID_MISSING | The client provided ID (cl_quote_req_id ) is missing in request-quote |
110031 | MISSING_SETTLE_TYPE | The settlement type is missing in request-quote |
110018 | INVALID_DEAL_CHANNEL | The deal channel is invalid |
110020 | DUPLICATE_CL_QUOTE_REQ_ID | The client provided ID (cl_quote_req_id ) already used for an open quote request |
110004 | LIQUIDITY_PROVIDER_NOT_FOUND | The liquidity provider specified in the request cannot be found or no liquidity providers are available for the requested instrument |
110043 | MISSING_LEG_INFO | The leg list is missing or empty in request-quote |
110013 | INVALID_OTC_INSTRUMENT | The OTC instrument specified in request-quote is invalid |
110025 | USER_NO_OTC_QR_ACCESS | User does not have access to perform request-quote |
213 | INVALID_ORDERQTY | The quantity specified in request-quote is invalid |
110050 | EXCEEDS_QUANTITY_LIMIT | The quantity specified in request-quote exceeds the maximum limit for the instrument |
238 | INVALID_NOTIONAL | The notional specified in request-quote is invalid |
110023 | NOTIONAL_AND_QTY_BOTH_PROVIDED | Cannot provide both quantity and notional in request-quote |
110024 | PROVIDED_FIELDS_MISSING | Must provide either quantity or notional in request-quote |
111002 | MARGIN_NOT_SUPPORTED | Settle later arrangement must be done using a settle later account |
110017 | INVALID_SETTLE_TYPE | Settle later arrangement must be IMMEDIATE or T1 |
220 | INVALID_SIDE | The side specified in request-quote is not one of the valid options (BUY or SELL ) |
Deal Reason Code
Code | HTTP Status | Reason | Description |
---|---|---|---|
208 | 400 | INSTRUMENT_NOT_TRADABLE | Instrument is not tradable |
238 | 500 | INVALID_NOTIONAL | Each leg’s notional in request-deal must be exactly the SAME as leg’s notional in request-quote |
308 | 400 | INVALID_PRICE | Each leg’s price in request-deal must be exactly the SAME as leg’s price in the quote |
401 | 400 | ACCOUNT_DOES_NOT_EXIST | Account ID not found in OTC |
420 | 500 | USER_NOT_FOUND | User ID not found in OTC |
110002 | 500 | OTC_IS_SUSPENDED | deal flow is suspended in OTC |
110009 | 500 | INVALID_DEAL_ID | deal-id is invalid |
110010 | 500 | DUPLICATE_DEAL_ID | OTC already has a deal with same deal-id |
110025 | 500 | USER_NO_OTC_QR_ACCESS | User does not have access to perform request-deal |
110026 | 500 | QUOTE_NOT_FOUND | OTC cannot find the quote given the quote-id |
110028 | 500 | QUOTE_REQUEST_NOT_FOUND | OTC cannot find the quote-req-id |
110029 | 500 | QUOTE_EXPIRED | quote is expired already |
110030 | 500 | QUOTE_NOT_ACTIVE | quote is not ACTIVE |
110032 | 500 | DUPLICATE_OTC_SYMBOL | For multi-leg RFQ, not allowed to have 2 legs with same instrument |
110033 | 500 | MISSING_OTC_SYMBOL | Must provide instrument in each leg for RFQ |
110034 | 500 | MISSING_SIDE | request-deal must indicate whether BUY or SELL |
110035 | 500 | SIDE_MISMATCH | request-deal side must be the same as request-quote |
110036 | 500 | QTY_MISMATCH | Each leg’s qty in request-deal must be exactly the SAME as leg’s qty in quote-request |
Websocket Termination Codes
Code | Description |
---|---|
1000 | Normal disconnection by server, usually when the heartbeat isn't handled properly |
1006 | Abnormal disconnection |
1013 | Server restarting -- try again later |
Error Response Format
Due to the asynchronous nature of websocket requests, a robust and consistent error response is crucial in order to match the response with the request.
To ensure API consistency for websocket error responses, if the id
and method
is omitted in the original request, id
will have a value of -1
and method
will have a value of ERROR
.
The original request will be returned as an escaped string in the original
field.
Reference Data API
private/otc/get-otc-instruments
Request Sample
{
"id": 1,
"method": "private/otc/get-otc-instruments",
"params": {
}
}
Response Sample
{
"id": 1,
"method": "private/otc/get-otc-instruments",
"code": 0,
"result": {
"instrument_list": [
{
"instrument_name": "BTC_USD",
"base_currency": "BTC",
"quote_currency": "USD",
"type": "SPOT",
"price_tick_size": "0.01",
"quote_decimals": 2,
"qty_tick_size": "0.00001",
"qty_decimals": 5
},
{
"instrument_name": "ETH_USD",
"base_currency": "ETH",
"quote_currency": "USD",
"type": "SPOT",
"price_tick_size": "0.01",
"quote_decimals": 2,
"qty_tick_size": "0.0001",
"qty_decimals": 4
}
]
}
}
Get a list of OTC instruments which takers would be able to get a quote.
Response Params
Field | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | instrument_list array | Y | See below |
instrument_list consists of:
Field | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | |
base_currency | string | Y | |
quote_currency | string | Y | |
type | string | Y | E.g., SPOT |
price_tick_size | string | Y | E.g., 0.01 |
quote_decimals | string | Y | E.g., 2 |
qty_tick_size | string | Y | |
qty_decimals | string | Y |
Applies To
REST Method
POST
Account Balance and Position API
Introduction
Account Balance and Position API
Transaction History
Account Balance and Position API: private/get-transactions
Wallet API
WebSockets Subscriptions
Introduction
One of the powerful features of a websocket is the ability to subscribe to incremental updates in particular channels.
This section covers the available channels that can be subscribed or unsubscribed for Quote Requests for RFQ, Quotes for RFQ, and Deals.
Websocket Heartbeats
public/auth
user.balance
user.positions
RFQ API [Taker]
Introduction
- Taker can firstly subscribes to the following WebSocket channels:
a. user.otc_qr.requests
b. user.otc_qr.quotes
c. user.otc.deals - Taker can create a quote request via WebSocket : private/otc/request-quote
- Taker, who will be notified of quotes from the WebSocket channel user.otc_qr.quotes, can create a deal request upon Quote message with private/otc/request-deal
- Taker will receive confirmation of the deal's status on WebSocket channel user.otc.deals
- Taker can get the rejected or completed quote request from Quote Query API
- Taker can get the rejected or completed deal from Deal Query API
user.otc_qr.requests [Taker]
Request Sample
{
"id": 1,
"method": "subscribe",
"params": {
"channels": ["user.otc_qr.requests"]
},
"nonce": 1587523073344
}
Subscription Response (AutoAck)
{
"id": -1,
"method": "subscribe",
"code": 0
}
Push Data Sample
// Return quote_req_id
{
"id": -1,
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc_qr.requests",
"channel": "user.otc_qr.requests",
"data": [
{
"cl_quote_req_id": "clQuoteReqId_123",
"quote_req_id": "4611686018427391634"
}
]
}
}
// Return ACTIVE status
{
"id": 1,
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc_qr.requests",
"channel": "user.otc_qr.requests",
"data": [
{
"cl_quote_req_id": "clQuoteReqId_123",
"quote_req_id": "4611686018427391634",
"status": "ACTIVE",
"reason": "NO_ERROR"
}
]
}
}
// Return REJECTED status
{
"id": 1,
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc_qr.requests",
"channel": "user.otc_qr.requests",
"data": [
{
"cl_quote_req_id": "clQuoteReqId_123",
"quote_req_id": "4611686018427625500",
"status": "REJECTED",
"reason": "INVALID_OTC_INSTRUMENT"
}
]
}
}
For Taker to subscribe to get quote request response / quote request status update from system
Request Params
Name | Type | Required | Description |
---|---|---|---|
method | string | Y | Should be “subscribe” |
channels | string array | Y | Channel(s) to subscribe to “user.otc_qr.requests“ |
Push Data
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | object | Y | See below |
result consists of:
Name | Type | Required | Description |
---|---|---|---|
subscription | string | Y | Should be user.otc_qr.requests |
channel | string | Y | Should be user.otc_qr.requests |
data | data array | N | See below |
data consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_req_id | string | Y | System generated unique ID for the quote |
cl_quote_req_id | string | Y | Client provided ID for the quote request |
status | string | N | ACTIVE user may receive a quote and user may call request-deal to execute a tradeREJECTED rejected due to various reasons; quote request is no longer validCOMPLETED quote request duration has expired and no longer valid. User will not receive quote nor able to call request-deal anymore |
reason | string | N | Reason if REJECTED |
Applies To
user.otc_qr.quotes [Taker]
Request Sample
{
"id": 1,
"method": "subscribe",
"params": {
"channels": ["user.otc_qr.quotes"]
},
"nonce": 1587523073344
}
Subscription Response (AutoAck)
{
"id": -1,
"method": "subscribe",
"code": 0
}
Push Data Sample
//Quantity RFQ
{
"id": -1,
"code": 0,
"method": "subscribe",
"result": {
"subscription": "user.otc_qr.quotes",
"channel": "user.otc_qr.quotes",
"data": [
{
"quote_id": "98765",
"cl_quote_req_id": "quote123456",
"quote_req_id": "88997712345",
"status": "ACTIVE",
"reason": "NO_ERROR",
"response_time_ns": "1749469877399174902",
"expiry_time_ns": "1749469885434000000",
"leg_list": [
{
"instrument_name": "BTC_USD",
"side": "BUY",
"quantity": "1",
"bid": "26000",
"ask": "26010",
"type": "PRICE"
}
]
}
]
}
}
//Notional RFQ
{
"id": -1,
"code": 0,
"method": "subscribe",
"result": {
"subscription": "user.otc_qr.quotes",
"channel": "user.otc_qr.quotes",
"data": [
{
"quote_id": "4611686018735120032",
"quote_req_id": "4611686018427681303",
"cl_quote_req_id": "1749471871607",
"status": "ACTIVE",
"reason": "NO_ERROR",
"response_time_ns": "1749471871741285050",
"expiry_time_ns": "1749471879771000000",
"leg_list": [
{
"instrument_name": "BTC_USD",
"side": "BUY",
"notional": "10000"
"bid": "88841",
"ask": "89852",
"type": "PRICE",
}
]
}
]
}
}
For Taker to subscribe to get quotes.
Request Params
Name | Type | Required | Description |
---|---|---|---|
method | string | Y | Should be “subscribe” |
channels | string array | Y | Channel(s) to subscribe to “user.otc_qr.quotes“ |
Push Data
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | json | Y | See below |
result consists of:
Name | Type | Required | Description |
---|---|---|---|
subscription | string | Y | Should be user.otc_qr.quotes |
channel | string | Y | Should be user.otc_qr.quotes |
data | quote array | N | See below |
quote consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_id | string | Y | System generated unique ID for the quote |
quote_req_id | string | Y | System generated unique ID for the quote request |
cl_quote_req_id | string | Y | Client provided ID for the quote request |
status | string | N | ACTIVE |
reason | string | N | Reason if not successful otherwise NO_ERROR |
response_time_ns | string | N | Unix epoch time when quote was generated in nanosecond |
expiry_time_ns | string | N | Unix epoch time when quote expires in nanosecond |
leg_list | leg_list array | Y | List of legs for the quote |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
side | string | N | The side provided in the quote request |
quantity | string | Y / N | Either quantity or notional |
notional | string | Y / N | Either quantity or notional |
bid | string | N | The bid price for the instrument |
ask | string | N | The ask price for the instrument |
type | string | N | PRICE . Only present when the quote has pricing (i.e. bid and ask) |
Applies To
private/otc/request-quote (RFQ)
Request Sample
{
"id": 12,
"method": "private/otc/request-quote",
"params": {
"cl_quote_req_id": "abcd13456",
"firm_quote": false,
"settlement_arrangement": "IMMEDIATE",
"duration": "10000",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "1",
"side": "BUY"
}
],
"quote_ttl": "5000"
}
}
Success Response Sample
{
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc_qr.requests",
"channel": "user.otc_qr.requests",
"data": [
{
"cl_quote_req_id": "1739951702774",
"quote_req_id": "4611686018427626536"
}
]
},
"id": -1
}
Failed Response Sample
{
"id": 12,
"method": "private/otc/request-quote",
"code": 40004,
"message": "Missing or invalid argument"
}
Create a quote request (RFQ flow).
Request Params
Name | Type | Required | Description |
---|---|---|---|
cl_quote_req_id | string | Y | Client provided ID for the quote request Should be unique per ACTIVE quote requestAccepted characters a-z , A-Z , 0-9 , _ , - |
firm_quote | boolean | N | FALSE / TRUE (default to FALSE )FALSE indicates the quoted price subject to changesTRUE indicates the quoted price is guaranteed |
settlement_arrangement | string | N | IMMEDIATE / T1 (default to IMMEDIATE )IMMEDIATE can only be used by non settle later accountT1 can only be used by settle later account |
duration | string | N | 5000 / 10000 / 30000 / 60000 / 300000 / 600000 (default to 10000 )Quote request goes from ACTIVE to COMPLETED after this duration (in millisecond) |
quote_ttl | string | N | 4000 / 5000 (default to 4000 )The minimum time the quotes remains valid (in millisecond) |
leg_list | leg_list array | Y | List of legs for the quote request |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
side | string | Y | BUY / SELL |
quantity | string | Y / N | Either quantity or notional must be provided but not both |
notional | string | Y / N | Either quantity or notional must be provided but not both |
Response Params
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | object | Y | See below |
result consists of:
Name | Type | Required | Description |
---|---|---|---|
subscription | string | Y | Should be user.otc_qr.requests |
channel | string | Y | Should be user.otc_qr.requests |
data | data array | N |
data consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_req_id | string | Y | System generated unique ID for the quote request |
cl_quote_req_id | string | Y | Client provided ID for the quote request |
Applies To
private/otc/request-deal (RFQ)
Request Sample
{
"id": 1,
"method": "private/otc/request-deal",
"params": {
"deal_type": "QUOTE_REQUEST",
"cl_deal_id": "client_id_1",
"leg_list": [
{
"instrument_name": "BTC_USD",
"price": "95734.2",
"quantity": "1",
"side": "BUY"
}
],
"quote_id": "4611686018492073851",
"quote_req_id": "4611686018427623960"
}
}
Success Response Sample
{
"id": 1,
"method": "private/otc/request-deal",
"code" : 0,
"result" : {
"cl_deal_id" : "client_id_1",
"deal_id" : "4611686018429016536",
"quote_req_id" : "4611686018427623960",
"quote_id" : "4611686018492073851",
"deal_type" : "QUOTE_REQUEST",
"deal_status" : "ACCEPTED",
"reason" : "NO_ERROR",
"update_time_ns" : "1739329285207188882",
"leg_list" : [
{
"instrument_name" : "BTC_USD",
"quantity" : "1",
"price" : "95734.2",
"side" : "BUY",
"type":"PRICE"
}
]
}
}
Failed Response Sample
{
"id": 1,
"method": "private/otc/request-deal",
"code" : 110026,
"message" : "QUOTE_NOT_FOUND"
}
Create a deal request for RFQ.
Request Params
Name | Type | Required | Description |
---|---|---|---|
deal_type | string | Y | Should be QUOTE_REQUEST |
cl_deal_id | string | Y | Client provided ID for the deal Should be unique per deal request Accepted characters a-z , A-Z , 0-9 , _ , - |
quote_id | string | Y | quote_id obtained from user.otc_qr.quotes |
quote_req_id | string | Y | quote_req_id obtained from user.otc_qr.requests |
leg_list | leg_list array | Y | List of legs for the quote request |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument symbol (e.g., BTC_USD) Same value used in request-quote |
price | string | Y | bid or ask obtained from user.otc_qr.quotes |
quantity | string | Y / N | Client either provide quantity or notional Same value used in request-quote |
notional | string | Y / N | Client either provide quantity or notional Same value used in request-quote |
side | string | Y | BUY or SELL |
Response Params
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | leg_list array | Y | See below |
result consists of:
Name | Type | Required | Description |
---|---|---|---|
deal_id | string | Y | System generated unique ID for the deal |
cl_deal_id | string | Y | Client provided ID for the deal request |
quote_id | string | Y | System generated unique ID for the quote |
quote_req_id | string | Y | System generated unique ID for the quote request |
deal_type | string | Y | Deal type |
deal_status | string | Y | ACCEPTED system received dealREJECTED deal rejected |
reason | string | Y | NO_ERROR |
update_time_ns | string | Y | Unix epoch time when deal last updated in nanosecond |
leg_list | leg_list array | Y | List of legs for the quote request |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument symbol (e.g., BTC_USD ) |
price | string | Y | Echoed back from quote |
quantity | string | Y / N | Echoed back from quote request if requested quantity |
notional | string | Y / N | Echoed back from quote request if requested notional |
executed_quantity | string | N | Executed quantity |
executed_notional | string | N | Executed notional |
side | string | Y | Echoed back from deal |
type | string | N | PRICE |
Applies To
RFQ Quote Query API
private/otc/get-open-quote-requests
Request Sample
{
"id": 12,
"method": "private/otc/get-open-quote-requests",
"params": {
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-open-quote-requests",
"code": 0,
"result": {
"count": 1,
"quote_request_list": [
{
"quote_req_id": "88997712345",
"cl_quote_req_id": "abcd13456",
"firm_quote": false,
"settlement_arrangement": "IMMEDIATE",
"status": "ACTIVE",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "1",
"side": "BUY",
"type": "PRICE"
}
],
"request_time_ns" : "1749104833703281311"
}
]
}
}
Get open quote requests. Only return active quote requests (status = NEW
or ACTIVE
)
Request Params
Name | Type | Required | Description |
---|---|---|---|
cl_quote_req_id | string | N | Client provided ID for the quote request |
quote_req_id | string | N | System generated unique ID for the quote request |
start_time | long | N | Start time in Unix time format (inclusive) Default: end_time - 1 day Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp Nanosecond is recommended for accurate pagination |
limit | int | N | Page size (default: 20, max: 200) Note: If start_time & end_time not provided, limit is not used. Default page size to 100 |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | quote_request_list array | Y | See below |
quote_request_list consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_req_id | string | Y | System generated unique ID for the quote request |
cl_quote_req_id | string | Y | Client provided ID for the quote request |
firm_quote | boolean | Y | The quoted price is guaranteed or subject to change |
settlement_arrangement | string | Y | Settlement arrangement of the Quote Request (IMMEDIATE , T1 ) |
status | string | Y | NEW or ACTIVE |
reason | string | Y | NO_ERROR |
request_time_ns | string | Y | Unix epoch time when quote request was created in nanoseconds |
leg_list | leg_list array | Y | List of legs for the open quote request |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
quantity | string | Y / N | Either quantity or notional |
notional | string | Y / N | Either quantity or notional |
side | string | Y | The side of the quote request |
type | string | N | PRICE |
Applies To
REST Method
POST
private/otc/get-open-quotes
Request Sample
{
"id": 12,
"method": "private/otc/get-open-quotes",
"params": {
"lp_quote_id": "98765"
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-open-quotes",
"code": 0,
"result": {
"count": 1,
"quote_list": [
{
"quote_id": "11223344556677",
"lp_quote_id": "98765",
"quote_req_id": "88997712345",
"status": "ACTIVE",
"reason": "NO_ERROR",
"response_time_ns": "1695153400000000000",
"expire_time_ns": "1696153400000000000",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "1",
"bid": "95085.99",
"ask": "96086.01",
"type": "PRICE"
}
]
}
]
}
}
Get open quotes. Only return active Quotes (status = ACTIVE
)
Request Params
Name | Type | Required | Description |
---|---|---|---|
quote_id | string | N | System supplied Quote ID; if provided, query will ignore time range |
lp_quote_id | string | N | LP supplied Quote ID; if provided, query will ignore time range |
start_time | long | N | Start time in Unix time format (inclusive) Default: end_time - 1 day Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp Nanosecond is recommended for accurate pagination |
limit | int | N | Page size (default: 20, max: 200) |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | quote_list array | Y | See below |
quote_list consists of:
Name | Type | Required | Description |
---|---|---|---|
lp_quote_id | string | Y | LP supplied ID for the quote |
quote_req_id | string | Y | System generated unique ID for the quote request |
status | string | Y | ACTIVE |
reason | string | Y | NO_ERROR |
response_time_ns | string | Y | Unix epoch time when quote was received in nanosecond |
expiry_time_ns | string | Y | Unix epoch time when quote expires in nanosecond |
leg_list | leg_list array | Y | See below |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
quantity | string | Y / N | Either quantity or notional |
notional | string | Y / N | Either quantity or notional |
bid | string | N | The bid price for the instrument |
ask | string | N | The ask price for the instrument |
type | string | N | PRICE . Only present when the quote has pricing (i.e. bid / ask) |
Applies To
REST Method
POST
private/otc/get-quote-request-history
Request Sample
{
"id": 12,
"method": "private/otc/get-quote-request-history",
"params": {
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-quote-request-history",
"code": 0,
"result": {
"count": 2,
"quote_request_list": [
{
"quote_req_id": "4611686018427625581",
"cl_quote_req_id": "abcd13456",
"firm_quote": false,
"settlement_arrangement": "IMMEDIATE",
"status": "COMPLETED",
"request_time_ns": "1747622246551416954",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "1",
"side": "BUY",
"type": "PRICE"
}
]
},
{
"quote_req_id": "4611686018427625594",
"cl_quote_req_id": "1739762096888",
"firm_quote": false,
"settlement_arrangement": "IMMEDIATE",
"status": "REJECTED",
"reason": "INVALID_OTC_INSTRUMENT",
"request_time_ns": "1747622246551416954",
"leg_list": [
{
"instrument_name": "ABC",
"quantity": "0.6",
"side": "BUY",
"type": "PRICE"
}
]
}
]
}
}
Get quote requests history. Only return closed quote requests (status = COMPLETED
/REJECTED
)
Request Params
Name | Type | Required | Description |
---|---|---|---|
cl_quote_req_id | string | N | Client provided ID for quote request |
quote_req_id | string | N | System generated unique ID for the quote request |
start_time | long | N | Start time in Unix time format (inclusive) Default: end_time - 1 day Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp Nanosecond is recommended for accurate pagination |
limit | int | N | Page size (default: 20, max: 200) |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | quote_request_list array | Y | See below |
quote_request_list consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_req_id | string | Y | System generated unique ID for the quote request |
cl_quote_req_id | string | Y | Client provided ID for the quote request |
firm_quote | boolean | Y | The quoted price is guaranteed or subject to change |
settlement_arrangement | string | Y | Settlement arrangement of the quote request (IMMEDIATE , T1 ) |
status | string | Y | COMPLETED /REJECTED |
reason | string | N | Reason if REJECTED |
request_time_ns | string | Y | Unix epoch time when quote request was created in nanoseconds |
leg_list | leg_list array | Y | See below |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
quantity | string | Y / N | Either quantity or notional |
notional | string | Y / N | Either quantity or notional |
side | string | Y | The side of the quote request |
type | string | N | PRICE |
Applies To
REST Method
POST
private/otc/get-quote-history
Request Sample
{
"id": 12,
"method": "private/otc/get-quote-history",
"params": {
"lp_quote_id": "98765"
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-quote-history",
"code": 0,
"result": {
"count": 1,
"quote_list": [
{
"lp_quote_id": "98765",
"quote_req_id": "88997712345",
"status": "ACTIVE",
"reason": "NO_ERROR",
"response_time_ns": "1695153400000000000",
"expire_time_ns": "1696153400000000000",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "1",
"bid": "100010",
"ask": "100000",
"type": "PRICE"
}
]
}
]
}
}
Get quotes history.
Request Params
Name | Type | Required | Description |
---|---|---|---|
quote_id | string | N | System supplied Quote ID; if provided, query will ignore time range |
lp_quote_id | string | N | LP supplied Quote ID; if provided, query will ignore time range |
start_time | long | N | Start time in Unix time format (inclusive) Default: end_time - 1 day Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp Nanosecond is recommended for accurate pagination |
limit | int | N | Page size (default: 20, max: 200) |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | quote_list array | Y | See below |
quote_list consists of:
Name | Type | Required | Description |
---|---|---|---|
quote_id | string | Y | System supplied Quote ID; |
lp_quote_id | string | Y | LP supplied Quote ID |
quote_req_id | string | Y | System generated unique ID for the quote request |
status | string | Y | |
reason | string | Y | |
response_time_ns | string | Y | Unix epoch time when quote was received in nanosecond |
expiry_time_ns | string | Y | Unix epoch time when quote expires in nanosecond |
leg_list | leg_list array | Y | See below |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
quantity | string | Y / N | Either quantity or notional |
notional | string | Y / N | Either quantity or notional |
bid | string | N | The bid price for the instrument |
ask | string | N | The ask price for the instrument |
type | string | N | PRICE . Only present when the quote has pricing (i.e. bid / ask) |
Applies To
REST Method
POST
Deal Query API
private/otc/get-open-deals
Request Sample
{
"id": 12,
"method": "private/otc/get-open-deals",
"params": {
"deal_type": "QUOTE_REQUEST"
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-open-deals",
"code": 0,
"result": {
"deal_list": [
{
"deal_id": "111222333444555777",
"quote_id": "98764",
"cl_deal_id": "external_deal_id_123",
"deal_type": "QUOTE_REQUEST",
"deal_status": "ACCEPTED",
"settlement_arrangement": "IMMEDIATE",
"create_time_ns": "1696152390000000000",
"update_time_ns": "1696152400000000000",
"quote_req_id": "77665544",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "0.1",
"executed_quantity": "0.1",
"executed_notional": "2600.05",
"price": "26000.5",
"side": "BUY",
"type": "PRICE"
}
]
}
]
}
}
Get deals for given user. Only return Deals that are not yet SETTLED (aka open deals). If no start_time or end_time provided, return recent 100 records.
Request Params
Name | Type | Required | Description |
---|---|---|---|
deal_type | string | Y | QUOTE_REQUEST |
deal_id | string | N | System generated unique ID for the Deal If provided, will ignore instrument_name , start_time , and end_time params |
instrument_name | string | N | Instrument symbol in otc_instrument table; will return a multi-leg deal if a leg contains the instrument |
start_time | long | N | Start time in Unix time format (inclusive) Default: end_time - 1 day Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp Nanosecond is recommended for accurate pagination |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | deal_list array | Y | See below Page size without start_time/end_time: 100 with start_time/end_time: 200 |
deal_list consists of:
Name | Type | Required | Description |
---|---|---|---|
deal_id | string | Y | System generated unique ID for the Deal |
quote_id | string | N | System generated unique ID for the Quote |
cl_deal_id | string | Y | Client provided ID for the deal |
deal_type | string | Y | QUOTE_REQUEST |
deal_status | string | Y | ACCEPTED system received dealCONFIRMED liquidity provider has executed dealSETTLED deal settled and funds transferedREJECTED deal rejected |
settlement_arrangement | string | Y | Settlement arrangement of the Deal (IMMEDIATE , T1 ) |
create_time_ns | string | Y | Create time of the Deal (in nanoseconds) |
update_time_ns | string | Y | Last updated time of the Deal (in nanoseconds) |
quote_req_id | string | Y | System generated unique ID for the quote request |
leg_list | leg_list array | Y | Contains the legs for this Deal |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument of the Deal (e.g., BTC_USD ) |
quantity | string | Y / N | Either quantity or notional of the Deal |
notional | string | Y / N | Either quantity or notional of the Deal |
executed_quantity | string | N | Executed qty of the Deal |
executed_notional | string | N | Executed notional of the Deal |
price | string | Y | Price of the Deal |
side | string | Y | The side of the deal |
type | string | N | PRICE |
Applies To
REST Method
POST
private/otc/get-deal-history
Request Sample
{
"id": 12,
"method": "private/otc/get-deal-history",
"params": {
"deal_type": "QUOTE_REQUEST",
"start_time": 1696154400000,
"end_time": 1697364000000
}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-deal-history",
"code": 0,
"result": {
"deal_list": [
{
"deal_id": "111222333444555777",
"quote_id": "98764",
"cl_deal_id": "external_deal_id_123",
"deal_type": "QUOTE_REQUEST",
"deal_status": "SETTLED",
"settlement_arrangement": "IMMEDIATE",
"create_time_ns": "1696152390000000000",
"update_time_ns": "1696152400000000000",
"quote_req_id": "77665544",
"leg_list": [
{
"instrument_name": "BTC_USD",
"quantity": "0.1",
"executed_quantity": "0.1",
"executed_notional": "2600.05"
"price": "26000.5",
"side": "BUY",
"type": "PRICE"
}
]
}
]
}
}
Get closed deals for given user.
Request Params
Name | Type | Required | Description |
---|---|---|---|
deal_type | string | Y | QUOTE_REQUEST |
deal_id | string | N | System generated unique ID for the Deal |
start_time | long | N | Start time in Unix time format (inclusive). Default: end_time - 1 day. Nanosecond is recommended for accurate pagination |
end_time | long | N | End time in Unix time format (exclusive) Default: current system timestamp. Nanosecond is recommended for accurate pagination |
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | deal_list array | Y | See below |
deal_list consists of:
Name | Type | Required | Description |
---|---|---|---|
deal_id | string | Y | System generated unique ID for the Deal |
quote_id | string | N | System generated unique ID for the Quote |
cl_deal_id | string | Y | Client provided ID for the deal |
deal_type | string | Y | QUOTE_REQUEST |
deal_status | string | Y | ACCEPTED system received dealCONFIRMED liquidity provider has executed dealSETTLED deal settled and funds transferedREJECTED deal rejected |
settlement_arrangement | string | Y | Settlement arrangement of the Deal (IMMEDIATE , T1 ) |
create_time_ns | string | Y | Create time of the Deal (in nanoseconds) |
update_time_ns | string | Y | Last updated time of the Deal (in nanoseconds) |
quote_req_id | string | Y | System generated unique ID for the quote request |
leg_list | leg_list array | Y | Contains the legs for this Deal |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument for this leg |
quantity | string | Y / N | Either quantity or notional of the Deal |
notional | string | Y / N | Either quantity or notional of the Deal |
executed_quantity | string | N | Executed qty of the Deal |
executed_notional | string | N | Executed notional of the Deal |
price | string | Y | |
side | string | Y | The side of the deal |
type | string | N | PRICE |
Applies To
REST Method
POST
Settle Later Query API
private/otc/get-settle-later-limit
Request Sample
{
"id": 12,
"method": "private/otc/get-settle-later-limit",
"params": {}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-settle-later-limit",
"code": 0,
"result": {
"account_id": "52e7c00f-1324-5a6z-bfgt-de445bde21c1",
"configured_limit": "1000000",
"used_limit": "20000"
}
}
Get used settle later limit as well as the configured limit for account.
Response
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | settle_later object | Y | See below |
settle_later consists of:
Name | Type | Required | Description |
---|---|---|---|
account_id | string | N | |
configured_limit | string | Y | E.g., 1000000 |
used_limit | string | Y | E.g., 200000 |
Applies To
REST Method
POST
private/otc/get-unsettled-amounts
Request Sample
{
"id": 12,
"method": "private/otc/get-unsettled-amounts",
"params": {}
}
Response Sample
{
"id": 12,
"method": "private/otc/get-unsettled-amounts",
"code": 0,
"result": {
"2024-08-14": {
"BTC": "2.321",
"USD": "122023.849"
},
"2024-08-15": {
"ETH": "2.321",
"USD": "122023.849"
}
}
}
Get pending settlement amount aggregated by date and instrument. Supported in rest gateway.
Request Params
Response Params
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | map by date and instrument | Y | Please refer to the sample code |
Applies To
REST Method
POST
Deal Websocket Subscriptions
user.otc.deals
Request Sample
{
"id": 1,
"method": "subscribe",
"params": {
"channels": ["user.otc.deals"]
},
"nonce": 1587523073344
}
Subscription Response (AutoAck)
{
"id": -1,
"method": "subscribe",
"code": 0
}
Push Data Sample
-- ACCEPTED status
{
"id": -1,
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc.deals",
"channel": "user.otc.deals",
"data": [
{
"deal_id": "4611686018429016536",
"deal_status": "ACCEPTED",
"reason": "NO_ERROR",
"quote_id": "4611686018492073851",
"deal_type": "QUOTE_REQUEST",
"update_time_ns": "1739329285207188882",
"quote_req_id": "4611686018427623960",
"leg_list": [
{
"price": "95734.2",
"instrument_name": "BTC_USD",
"side": "BUY",
"quantity": "1",
"type": "PRICE"
}
]
}
]
}
}
-- CONFIRMED status
{
"id": 1
"method": "subscribe",
"code": 0,
"result": {
"subscription": "user.otc.deals",
"channel": "user.otc.deals",
"data": [
{
"deal_id": "4611686018429016536",
"deal_status": "CONFIRMED",
"reason": "NO_ERROR",
"quote_id": "4611686018492073851",
"deal_type": "QUOTE_REQUEST",
"update_time_ns": "1739329288621704792",
"quote_req_id": "4611686018427623960",
"leg_list": [
{
"price": "95734.2",
"executed_quantity": "1",
"executed_notional": "95734.2",
"instrument_name": "BTC_USD",
"side": "BUY",
"quantity": "1",
"type": "PRICE"
}
]
}
]
}
}
For Taker to subscribe to get updates of the Deals requested by Taker.
Request Params
Name | Type | Required | Description |
---|---|---|---|
method | string | Y | Should be “subscribe” |
channels | string array | Y | Channel(s) to subscribe to “user.otc.deals“ |
Push Data
Name | Type | Required | Description |
---|---|---|---|
id | number | N | Echo back the request identifier from the original request |
method | string | Y | Method invoked |
code | number | Y | 0 for success; otherwise, see error details |
result | object | Y | See below |
result consists of:
Name | Type | Required | Description |
---|---|---|---|
subscription | string | Y | Should be user.otc_qr.requests |
channel | string | Y | Should be user.otc_qr.requests |
data | deal array | N | See below |
data consists of:
Name | Type | Required | Description |
---|---|---|---|
deal_id | string | Y | System generated unique ID for the deal |
cl_deal_id | string | Y | Client provided ID for the deal request |
quote_id | string | Y | System generated unique ID for the quote |
quote_req_id | string | Y | System generated unique ID for the quote request |
deal_type | string | Y | Deal type |
deal_status | string | Y | ACCEPTED system received dealCONFIRMED liquidity provider has executed dealSETTLED deal settled and funds transferedREJECTED deal rejected |
reason | string | Y | NO_ERROR |
update_time_ns | string | Y | Unix epoch time when deal last updated in nanosecond |
leg_list | leg_list array | Y | List of legs for the deal |
leg_list consists of:
Name | Type | Required | Description |
---|---|---|---|
instrument_name | string | Y | Instrument symbol (e.g., BTC_USD ) |
price | string | Y | Echoed back from quote |
quantity | string | Y / N | Echoed back from quote request if requested quantity |
notional | string | Y / N | Echoed back from quote request if requested notional |
executed_quantity | string | N | Executed quantity |
executed_notional | string | N | Executed notional |
side | string | Y | Echoed back from deal |
type | string | Y | PRICE |
Applies To
Common Issues
TOO_MANY_REQUESTS After Websocket Connects
Websocket rate limits are pro-rated based on the calendar-second that the websocket connection was opened.
This means, depending on the fraction of the calendar-second that the connection was established, the rate limit could be pro-rated to a small number.
By adding a 1-second sleep after establishing the websocket connection, and before requests are sent, this will ensure the rate limit is properly reset and sync'd to your session.
This will avoid occurrences of rate-limit (TOO_MANY_REQUESTS
) errors.
INVALID_NONCE On All Requests
The nonce should be the UTC Unix timestamp in milliseconds.
If this has been carefully checked, then the issue occurs when the system clock of the client machine is greater than 60 seconds in the future / past.
Usually, re-syncing with the NTP time server on the client machine will correct the issue.
If the issue persists, you can try deliberately subtracting N seconds from the nonce to force it to be N seconds in the past, which is still within the 60-second past tolerance.