Introduction
Communication Protocol(s) Conventions
- All method names (in JSON) and URLs are in ‘dash-case’
- For HTTP(s) and WSS API’s no custom http headers are used, full message payload is set as a message body
- For private HTTP(s) APIs (that include api_key and signature) we will be using only POST messages for everything. The payload is always delivered in the HTTP message body
- For public HTTP(s) API the GET messages are used and parameters are sent as part of the URL
- Web-socket communication follows the https://www.rfc-editor.org/rfc/rfc6455, this includes WS-level Ping-Pong frames support
- HTTP: https://api.uat.pintupro.com
- Websocket: wss://stream.uat.pintupro.com
Field Parameters Conventions
- We use ‘snake_case’ in parameters naming
- We use full uppercase and ‘snake_case’ for enum values
- For unique order identifier we will be using UIDv4. This includes (for each client)
- trade_id
- order_id
- For client_order_id uniqueness should be within one trading day (00:00:00.000000 - 23:59:59.999999), duplication will not be accepted during the one day period
- Symbols will follow a For the symbols naming the ‘dash-case’ is used and the names are in upper case (examples: BTC-IDR, ETH-IDR, BTC-ETH, etc.)
API - Messages Format Specification
General Message Format
Irrespective of the communication channel, ether HTTP(s) or WSS, each send/received message has the respective wrapper fields/values around it. Such fields are used to ensure the proper sequencing between clients and gateways.
Below is the representations of respective wrappers:
Request Wrapper (GET)
There is a set of the public API requests that can be only done via the HTTP(s) GET calls. For such requests there’s no body wrapper structure and all the required dedicated request parameters are set in the URL as respective parameters
Request Wrapper (POST and WSS)
Request warpper example for POST Message
{
"request_id": "b1ea627c-8288-4489-b0c0-d2eba01ca96c",
"method": "private/place-order",
"api_key": "abc0",
"params": {
"price": "1015979000",
"side": "BUY",
"size": "0.001",
"symbol": "BTC-IDR",
"time_in_force": "GTC",
"type": "LIMIT"
},
"timestamp": 1719292078182,
"signature": "53129569a2f541975bd6dd68b6608b4a0f318cc77948c012bc1994ff5276f014"
}
Private requests can be sent either via POST HTTP call to respective API endpoint or via WebSocket. The message format is the same for both HTTP and WSS endpoints. Each request contains:
Field | Type | Required | Description |
---|---|---|---|
request_id | string | no | ID of a request (preferably UUID). Generated by the client. The gateway will use the same id in the response so client can match request/response on its end. In case if the field is not set, the gateway will use same value as timestamp field as request_id |
timestamp | integer | yes | timestamp(unix milli) of when the request is sent. NOTE: the timestamp should be within an acceptable range and client’s clock should be at least in NTP sync. If timestamp is more than 10 seconds older or 1 second in the future compared to server time, such request will be rejected. |
api_key | string | yes | API key of a client |
signature | string | depends | hashed value consisting of data (including timestamp) that is signed using SHA256 along with client’s API secret. Should be always set in case of the POST call. In case is the WSS call is ignored (but WSS should authenticate itself with the respective authentication call) |
method | string (enum) | yes | method of the APIs (place-order, list-orders, cancel-order, list-trades) |
params | object | yes | payload that will be processed |
Response Wrapper
Response returned by the exchange follows the format defined in the table below.
Success response example
{
"request_id": "a498b06a-5e0b-469a-84c2-3ab27d301633",
"timestamp": 1719304915127,
"method": "private/place-order-list",
"code": 0,
"message": "SUCCESS",
"data": {
"results": [
{
"index": 0,
"code": 0,
"message": "SUCCESS",
"reason": "",
"order_id": "e1d90562-1b70-4c93-b25a-be8d485ea9a9",
"client_order_id": "31f767cb-d826-4bef-b799-f6f9cdf2c11f"
}
]
}
}
Error Response Example
{
"request_id": "364b73b6-5d3a-43c0-b48c-eee4766811f8",
"timestamp": 1719304987707,
"method": "private/cancel-order-list",
"code": 4,
"message": "FAILED",
"reason": "all orders failed to be canceled",
"data": {
"results": [
{
"index": 0,
"code": 7,
"message": "ORDER_NOT_FOUND"
},
{
"index": 1,
"code": 7,
"message": "ORDER_NOT_FOUND"
}
]
}
}
Field | Type | Description |
---|---|---|
request_id | string | ID of a client request (as set by the client) |
timestamp | integer | timestamp(unix milli) of when the response is sent |
method | string (enum) | method that was invoked by the client |
channel | string | name of the channel for the subscription stream, see Data Stream for details. NOTE: only is set when method is set to “subscription” |
code | integer | code related to the response status, see API Response Code Mapping for details |
message | string (enum) | message description related to the response status |
reason | string | text description of the error code/message for debugging and analysis purposes NOTE: will only be set/sent in case of non-successful response |
data | object | data of the response |
API - Signature Computation
We are usuing the HMAC-SHA256 signature calculation based on API Secret.
- To compute the signature, client should first create a data_string by serializing the request
params
in a specific way:
- The params object should be sorted based on key in ascending order
- The sorted object should be converted to the string (called
data_string
below) via combining keys and values one by one without any separators - For example
"params": {"name": "Harry", "active": false, "age": 11}
will givedata_string
valueactivefalseage11nameHarry
* - When params object is empty, null or absent it is represented by an empty string
- The params object should be sorted based on key in ascending order
- Then the signature is calculated as HMAC-SHA256 using API Secret as a key and payload as a concatenation result of
request_id
+timestamp
+method
+api_key
+data_string
. Bytes returned by HMAC-SHA256 are encoded as a hexadecimal string. - Computed HMAC hexadecimal string is added to the request wrapper payload as the
signature
field.
For example given api key
"abc0"
and secret"abc"
a valid signedplace-order
request would be:
{
"request_id": "fc9f3e2e-6791-49ac-af23-715fccac13dd",
"method": "private/place-order",
"api_key": "abc0",
"params": {
"price": "1015979000",
"side": "BUY",
"size": "0.001",
"symbol": "BTC-IDR",
"time_in_force": "GTC",
"type": "LIMIT"
},
"timestamp": 1719295943513,
"signature": "2094afd679b8a8afe1a74350aa5a3f05329309ce48ac9a4f05e28750be2c4ed4"
}
For this request the string to sign is
"fc9f3e2e-6791-49ac-af23-715fccac13dd1719295943513private/place-orderabc0price1015979000sideBUYsize0.001symbolBTC-IDRtime_in_forceGTCtypeLIMIT"
.
API - Response Codes Mapping
Internal Code (Current) | HTTP status | Message | Reason (description) | Developer Notes |
---|---|---|---|---|
17 | 429 | TOO_MANY_REQUESTS | See API - Rate Limits | |
0 | 200 | SUCCESS | executed successfully, no issues “empty reason” | |
1 | 200 | BAD_SYMBOL | - Unsupported Symbol | - Not found in reference data |
2 | 400 | BAD_REQUEST | Withdrawal: - Address not whitelisted - Invalid network - Invalid amount (Must be a number) - Amount must be greater than 0 - Amount must be greater than minimum withdrawal fee - Duplicate request ID - Invalid asset Spot: - empty symbol - page should be more than or equal to 0 - page size should be 1 to 200 - empty order ID and client order ID - TEnd should be greater than TStart - TStart and TEnd should be within 24 hours - symbol or tradeIds is required - both TStart and TEnd should be specified |
|
3 | 200 | ORDER_REJECTED | - price is not divisible by price_tick_size - size is not divisible by quantity_tick_size - order value above maximum - order value below minimum - exceeding maximum order size - below minimum order size - sell price should be within the band - buy price should be within the band |
|
4 | 200 | FAILED | all orders failed to be cancelled | |
5 | 200 | PARTIAL_SUCCESS | failed to place all orders | |
7 | 200 | ORDER_NOT_FOUND | Order not found | |
8 | 500 | INTERNAL_ERROR | ||
9 | - | HEARTBEAT_TIMEOUT | client did not respond to heartbeat, closing connection | |
10 | 200 | INSUFFICIENT_BALANCE | insufficient balance | |
11 | 400 | TIMESTAMP_EXPIRED | the timestamp sent in the request is out of sync with the server timestamp | |
12 | 400 | INVALID_METHOD | ||
10 | INSUFFICIENT_BALANCE | didn’t reach minimum amount |
API - WebSocket Channels Subscription
Channels Subscription
Websocket connections allow for subscriptions to streaming data over the dedicated channel. For this, there’s a dedicated subscribe method available as part of the request wrapper:
Field | Type | Required | Description |
---|---|---|---|
channels | array of strings | yes | name of the respective channel to which we need to subscribe to or unsubscribe from |
Example subscription request:
{
"request_id": "0331f39d-a300-4b94-a015-f75a9aba8cea",
"timestamp": 1719305357836,
"method": "subscribe",
"params": {
"channels": [
"trades.SOL-IDRT",
"aggrbook.snapshot.10.SOL-IDRT"
]
}
}
Successful Subscription response (in case of multiple channels):
{
"request_id": "d19b92b1-cbfb-4e4e-a7da-74772389a4b1",
"timestamp": 1719310184345,
"method": "subscribe",
"code": 0,
"message": "SUCCESS",
"data": {
"channel": "trades.SOL-IDR"
}
}
{
"request_id": "d19b92b1-cbfb-4e4e-a7da-74772389a4b1",
"timestamp": 1719310184345,
"method": "subscribe",
"code": 0,
"message": "SUCCESS",
"data": {
"channel": "aggrbook.snapshot.10.SOL-IDR"
}
}
Error Subscription response:
{
"request_id": "c74938d1-c128-498b-8107-8712c31a4b9e",
"timestamp": 1719305584322,
"method": "subscribe",
"code": 2,
"message": "BAD_REQUEST",
"reason": "unknown channel name",
"data": {
"channel": "nonexistent"
}
}
Channels to subscribe can be both public and private. In case of the private channel the Websocket Channels Subscription routine should be performed first.
One subscription message can contain an array of channels to subscribe to. The subscription replies will be one per requested channel.
Public channels:
Channel Name | Description |
---|---|
aggrbook.snapshot.{num_levels}.{symbol} | aggregated book snapshot for {num_levels} levels of symbol {symbol} |
trades.{symbol} | trades happened in the matching engine for symbol {symbol} |
Private channels:
Channel Name | Description |
---|---|
user.orders.{symbol} | statuses updates for all orders sent for a given symbol {symbol} |
user.orders | statuses updates for all order for all symbols |
user.trades.{symbol} | trades/fills notifications for a given symbol {symbol} |
user.trades | trades/fills notification for all symbols |
user.balance.snapshot | periodic updates of user’s account balance |
The response for the channel subscription comes in the form of Generic Response Wrapper (both success and error), with the following addition:
- there’s additional channel
field sent back with the name of the channel the message belongs to, it’s a part of data
field and is always sent.
Channel Unsubscription
You can unsubscribe from the required channel at any point in time. For this you can use the similar Subscription request wrapper, but with “method”: “unsubscribe” field. Response structure is similar as subscription response.
Channel Data Stream
In case the subscription to the channel is successful and the respective return code is returned, gateway will start streaming the data to the client. The stream message has the following fields:
Field | Type | Description |
---|---|---|
timestamp | integer | gateway timestamp(unix milli) when the message was sent to the client |
method | string | always “subscription” to show that the message is the channel data message |
channels | string | the actual name of the channel the update is sent for |
data | object | subscription stream message payload data object |
Channel Data Stream Errors
In case any unrecoverable application or the protocol error is encountered during the subscription streaming process, the gateway will close the web-socket with the respective Close Frame specifying the closure status code.
Heartbeats
In order to ensure the client’s liveness, the backend gateway may from time to time send the respective heartbeat request to which client needs to send the response within 10 seconds from time frame from the value specified in request.
Failure to reply to heartbeat request within the given time frame will result in server terminating the websocket connection.
Example of heartbeat request message:
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976772,
"method": "heartbeat-request"
}
Example of heartbeat response message:
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869978800,
"method": "heartbeat-response"
}
request_id
in the response has to match the one in request.
API - Rate Limits
Our API uses a weighted rate limiting strategy where each account has X
number of tokens every second and each endpoint, e
, has a different cost, Ce
. And the following limit will be enforced every window of a second.
sum(Ce*Ne) <= X
where Ne
is the number of calls made on endpoint e
in that window of a second.
Response
When rate limit is exceeded, expect to receive code=17
in the response message and message=TOO_MANY_REQUESTS
.
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1672304484978,
"method": "public/get-book",
"code": 17,
"message": "TOO_MANY_REQUESTS",
}
Default Limits
Account Type | Tokens Per Second |
---|---|
Market Maker | 50000 |
Costs
Method | Cost Assigned |
---|---|
public/get-book | 500 |
public/get-symbols-reference | 100 |
public/get-trades | 100 |
public/get-network-reference | 200 |
public/get-candlesticks | 300 |
public/get-ticker | 100 |
public/trading-fees-and-limits | 500 |
public/exchange-status | 100 |
private/place-order | 1000 |
private/place-order-list | 1500 |
private/cancel-order | 1000 |
private/cancel-order-list | 1250 |
private/cancel-all-orders | 1250 |
private/get-open-orders | 100 |
private/get-order-details | 300 |
private/get-order-history | 1000 |
private/get-trade-history | 1000 |
private/get-account-information | 100 |
private/get-funds-transfer-history | 1000 |
private/get-withdrawal-status | 1000 |
private/create-withdrawal | 1000 |
private/confirm-withdrawal | 2000 |
private/get-deposit-addresses | 1000 |
Public API
Websocket Authentication
Example websocket "public/auth" request:
{
"request_id": "837873eb-0d68-457b-860f-a853046455cf",
"timestamp": 1719306245083,
"method": "public/auth",
"api_key": "abc0",
"signature": "6d13d543b959454eb6b05ac5d3722aad3d9cd7a887d5083fb1818d18e34cff36"
}
Example response:
{
"request_id": "837873eb-0d68-457b-860f-a853046455cf",
"timestamp": 1719306245342,
"method": "public/auth",
"code": 0,
"message": "SUCCESS",
"data": null
}
Authentication call should be done before any private WSS method call or private WSS subscription is done over the established websocket session. If not done in such order, every private API request will be rejected.
Authentication request is a simple signed request wrapper without a params field.
In case of successful authentication, the response wrapper with code = 0 value will be returned, meaning that the connection is authorized for listening to private channels or executing private requests without providing api_key and signature on the upcoming requests messages during this websocket session.
Get Book
GET /v1/public/get-book?symbol=DOGE-IDR&depth=1
{
"timestamp": 1719306524062,
"method": "public/get-book",
"code": 0,
"message": "OK",
"data": {
"symbol": "DOGE-IDR",
"bids": [
[
"2018",
"58290.1",
"1"
]
],
"asks": [
[
"2021",
"58295",
"1"
]
]
}
}
Retrieves the latest snapshot of orderbook for a given instrument.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP GET | /v1/public/get-book?symbol=BTC-IDR&depth=10 |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "public/get-book", "params": { "symbol": "BTC-IDR", "depth": 10 } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | Symbol name |
depth | integer | no | The depth (number of price levels) of the market data book. Default is 1 for level 1 order book (quotes). Valid values are 1 or 10. |
Response Parameters - Body:
Field | Type | Description |
---|---|---|
data.symbol | string | Symbol name |
data.bids | array (string) | Price levels ordered by descending by price. Each price level is three elements array of decimals. Bids array: [0] = Price, [1] = Quantity, [2] = Number of Orders |
data.asks | array (string) | Price levels ordered by descending by price. Each price level is three elements array of decimals. Bids array: [0] = Price, [1] = Quantity, [2] = Number of Orders |
Get Symbol Reference
GET /v1/public/get-symbols-reference
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1672304484978,
"method": "public/get-symbols-reference",
"code": 0,
"message": "SUCCESS",
"reason": "",
"data": {
"symbols": [
{
"symbol": "BTC-USDT",
"quote_asset": "USDT",
"base_asset": "BTC",
"price_decimals": 7,
"size_decimals": 0,
"max_size": "1000000000",
"min_size": "10",
"max_value": "85000000",
"min_value": "10000",
"max_price": "1000",
"min_price": "0.0000001",
"quantity_tick_size": "10",
"price_tick_size": "0.0000001",
"last_updated_at": 1666261193053
},
{
"symbol": "ETH-USDT",
"quote_asset": "USDT",
"base_asset": "ETH",
"price_decimals": 7,
"size_decimals": 0,
"max_size": "1000000000",
"min_size": "10",
"max_value": "85000000",
"min_value": "10000",
"max_price": "1000",
"min_price": "0.0000001",
"quantity_tick_size": "10",
"price_tick_size": "0.0000001",
"last_updated_at": 1666261193053
}
]
}
}
Retrieves the reference data details for the instruments listed on Pro.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP GET | /v1/public/get-symbols-reference |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "public/get-symbols-reference", "params": {} } |
Response Parameters - Body:
Field | Type | Description |
---|---|---|
data.symbol | string | An array of symbols |
data.symbols[index].symbol | string | e.g. BTC-USDT |
data.symbols[index].base_asset | string | e.g. BTC |
data.symbols[index].quote_asset | string | e.g. USDT |
data.symbols[index].price_decimals | integer | Maximum decimal places for specifying price |
data.symbols[index].size_decimals | integer | Maximum decimal places for specifying size |
data.symbols[index].max_size | string | Maximum size |
data.symbols[index].min_size | string | Minimum size |
data.symbols[index].max_value | string | Maximum value in quote |
data.symbols[index].min_value | string | Minimum value in quote |
data.symbols[index].max_price | string | Maximum price |
data.symbols[index].min_price | string | Minimum price |
data.symbols[index].quantity_tick_size | string | Quantity tick size |
data.symbols[index].price_tick_size | string | Price tick size |
data.symbols[index].last_updated_at | integer | Instrument last update time (Unix timestamp) |
Get Trades
GET /v1/public/get-trades?symbol=WIF-IDR
{
"timestamp": 1719307521557,
"method": "public/get-trades",
"code": 0,
"message": "OK",
"data": {
"trades": [
{
"side": "SELL",
"price": "30663",
"size": "0.32",
"timestamp": 1719307508796,
"symbol": "WIF-IDR"
},
{
"side": "BUY",
"price": "30694",
"size": "0.32",
"timestamp": 1719307494778,
"symbol": "WIF-IDR"
},
{
"side": "SELL",
"price": "30649",
"size": "0.32",
"timestamp": 1719307478759,
"symbol": "WIF-IDR"
}
]
}
}
Retrieves the Public Trades information (public information about the orders filled). A max fixed number of the latest trades is returned.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP GET | /v1/public/get-trades?symbol=WIF-IDR |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 1719307478759 "method": "public/get-trades", "params": { "symbol": "WIF-IDR" } } |
Request Parameters
Field | Type | Description |
---|---|---|
symbol | string | Symbol name |
Response Parameters - Body:
Field | Type | Description |
---|---|---|
trades[index].side | string | Side of the taker order (buy or sell) |
trades[index].price | string | Trade price |
trades[index].size | string | Trade quantity |
trades[index].timestamp | integer | Trade timestamp |
trades[index].symbol | string | Symbol name |
Trading Private API (Authentication Required)
Place Order
Place order request example
{
"request_id": "fc9f3e2e-6791-49ac-af23-715fccac13dd",
"method": "private/place-order",
"api_key": "abc0",
"params": {
"price": "1015979000",
"side": "BUY",
"size": "0.001",
"symbol": "BTC-IDR",
"time_in_force": "GTC",
"type": "LIMIT"
},
"timestamp": 1719295943513,
"signature": "2094afd679b8a8afe1a74350aa5a3f05329309ce48ac9a4f05e28750be2c4ed4"
}
Place order success response example
{
"request_id": "28fca426-3d70-4f27-9171-4ef62cb3ae42",
"timestamp": 1719289547020,
"method": "private/place-order",
"code": 0,
"message": "SUCCESS",
"data": {
"order_id": "0a6cd728-31c9-49e4-be86-9d74a7976440",
"client_order_id": "99a230b8-8073-44ee-89f8-272dd8a37ed8"
}
}
Place order rejected response
{
"request_id": "68861317-b13a-4bf2-ba71-b74f9d0b4b23",
"timestamp": 1719307871325,
"method": "private/place-order",
"code": 3,
"message": "ORDER_REJECTED",
"reason": "exceeding maximum order size 0.5",
"data": {
"order_id": "",
"client_order_id": ""
}
}
The client is kindly requested to provide a unique client_order_id. Our trading system solely verifies the uniqueness of the client order ID against the user's existing active orders. Consequently, it is possible for the client to submit two orders with the same client_order_id, provided that the orders' lifecycles do not intersect with each other.
The place order request reply only confirms whether the order passed all the validity checks, being assigned its unique order_id and is enroute to the orderbook. To check whether the order’s actual status the historical information should be checked, or WSS subscription to user.orders channel should be made to listen for order status updates.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/place-order Limit Order { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/place-order", "params": { "symbol": "BTC-IDR", "side": "BUY", "type": "LIMIT", "price": "350000000", "size": "1.005", "client_order_id": "my-client-order-id-1", "time_in_force": "GTC", "exec_inst": "POST_ONLY", } } |
Websocket | Market Order { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/place-order", "params": { "symbol": "BTC-IDR", "side": "BUY", "type": "MARKET", "notional": "1000000", "client_order_id": "my-client-order-id-1" } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | Symbol the order is to be place for |
side | enum(string) | yes | BUY or SELL |
type | enum(string) | yes | order type, currently supported types are: MARKET, LIMIT |
price | string | depends | For LIMIT order type only: price the order is expected to be executed |
size | string | depends | For LIMIT and MARKET orders: qty to be either bought or sold NOTE: will be ignored in case notional is set for MARKET (BUY) order |
notional | string | depends | For MARKET (BUY) order only: amount to spend |
client_order_id | string | no | clients unique identified for this order |
time_in_force | string | depends | For LIMIT order type only: order lifetime params, options are (IOC,FOK,GTC) |
exec_inst | string | depends | For LIMIT order type only: order execution instructions, options are (empty,POST_ONLY) |
Response Parameters - Body:
Field | Type | Description |
---|---|---|
data.order_id | string (uidv4) | unique order identifier assigned by Exchange in case order passed all the checked and is routed to the respective matching engine |
data.client_order_id | string | assigned by client custom id that should be returned together with the order status updates later. Should be unique during one full trading day NOTE: if not provided by the client, will contain same value as timestamps. Yet, clients are encouraged to use client_order_id explicitly |
Place Order List
Place order list response example
{
"request_id": "603cffcf-79d2-4c53-a66f-d3008d487716",
"timestamp": 1719308208488,
"method": "private/place-order-list",
"code": 0,
"message": "SUCCESS",
"data": {
"results": [
{
"index": 0,
"code": 0,
"message": "SUCCESS",
"reason": "",
"order_id": "998271f3-0a0c-4f3f-becc-d31e0837f458",
"client_order_id": "8af646e9-7ec1-4508-a2c8-201ad10126c3"
},
{
"index": 1,
"code": 0,
"message": "SUCCESS",
"reason": "",
"order_id": "d816983d-b8ae-4f46-a5a7-75c767a20433",
"client_order_id": "a9486476-1d05-4961-b410-cf3bebc16b06"
}
]
}
}
Partial Rejected Place Order List response example
{
"request_id": "c34795b2-d793-4a01-aa5a-a32195d759e7",
"timestamp": 1718808872662,
"method": "private/place-order-list",
"code": 5,
"message": "PARTIAL_SUCCESS",
"reason": "failed to place some orders",
"data": {
"results": [
{
"index": 0,
"code": 3,
"message": "ORDER_REJECTED",
"reason": "buy price should be within the band 7500-22500",
"order_id": "",
"client_order_id": "de392715-d105-499d-9d40-401d618ead61"
},
{
"index": 1,
"code": 0,
"message": "SUCCESS",
"reason": "",
"order_id": "12b81ba3-4eb4-4dff-bfcd-f6142f5632a6",
"client_order_id": "c8ab10ce-4993-4c6d-ad97-19cb6eedac5d"
}
]
}
}
Request that is able to place a number of orders by utilizing a single API call.
The client is kindly requested to provide a unique client_order_id. Our trading system solely verifies the uniqueness of the client order ID against the user's existing active orders. Consequently, it is possible for the client to submit two orders with the same client_order_id, provided that the orders' lifecycles do not intersect with each other.
The place order request reply only confirms whether the order passed all the validity checks, being assigned it’s unique Exchange side order_id and is enroute to the orderbook. To check whether the order’s actual status the historical information should be checked, or WSS subscription to user.orders channel should be made for listen for updates.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/place-order-list { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/place-order-list", "params": { "orders": [ { "symbol": "BTC-IDR", "side": "BUY", "type": "LIMIT", "price": "350000000", "size": "1.005", "client_order_id": "my-client-order-id-1", "time_in_force": "GTC", "exec_inst": "POST_ONLY", }, { "symbol": "BTC-IDR", "side": "BUY", "type": "MARKET", "notional": "1000000", "client_order_id": "my-client-order-id-2" }, ... ] } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/place-order-list", "params": { "orders": [ { "symbol": "BTC-IDR", "side": "BUY", "type": "LIMIT", "price": "350000000", "size": "1.005", "client_order_id": "my-client-order-id-1", "time_in_force": "GTC", "exec_inst": "POST_ONLY", }, { "symbol": "BTC-IDR", "side": "BUY", "type": "MARKET", "notional": "1000000", "client_order_id": "my-client-order-id-2" }, ... ] } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
orders | array(object) | yes | array of the order records to be places. Max 10 elements Each record follows the parameters schema described below |
symbol | string | yes | Symbol the order is to be place for |
side | enum(string) | yes | BUY or SELL |
type | enum(string) | yes | order type, currently supported types are: MARKET, LIMIT |
price | string | depends | For LIMIT order type only: price the order is expected to be executed |
size | string | depends | For LIMIT and MARKET orders: qty to be either bought or sold NOTE: will be ignored in case notional is set for MARKET (BUY) order |
notional | string | depends | For MARKET (BUY) order only: amount to spend |
client_order_id | string | no | clients unique identified for this order |
time_in_force | string | depends | For LIMIT order type only: order lifetime params, options are (IOC,FOK,GTC) |
exec_inst | string | depends | For LIMIT order type only: order execution instructions, options are (empty,POST_ONLY) |
Request Parameters - Response Body:
Field | Type | Required | Description |
---|---|---|---|
data.results | string | yes | result array where each index represents the object that contains the result of the orders list placement. Below are the object fields: |
data.results.[index].index | integer | yes | index of the element in request array |
data.results.[index].code | integer | yes | new order placement execution code |
data.results.[index].message | string | yes | new order placement execution message code |
data.results.[index].reason | string | depends | in case new order placement placement is rejected, reason of the rejection |
data.results.[index].client_order_id | string | yes | assigned by client custom id that should be returned together with the order status updates later. Should be unique during one full trading day NOTE: if not provided by the client, will contain same value as timestamps. Yet, clients are encouraged to use client_order_id explicitly |
data.results.[index].order_id | string (uidv4) | depends | unique order identifier assigned by Exchange in case order passed all the checked and is routed to the respective matching engine |
Cancel All Orders
Success response
{
"request_id": "66959af9-7d6e-446a-8394-e458b58aecea",
"timestamp": 1719240172638,
"method": "private/cancel-all-orders",
"code": 0,
"message": "SUCCESS"
}
Rejected response example
{
"request_id": "66959af9-7d6e-446a-8394-e458b58aecea",
"timestamp": 1719245275196,
"method": "private/cancel-all-orders",
"code": 1,
"message": "BAD_SYMBOL",
"reason": "unsupported symbol"
}
The cancel all orders request reply only confirms whether the cancellation instruction is successfully placed. To check whether the orders are actually cancelled or not, detailed order historical information should be checked, or WSS subscription to user.orders channel should be made for listen for updates.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/cancel-all-orders { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/cancel-all-orders", "params": { "symbol": "BTC-IDR" } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/cancel-all-orders", "params": { "symbol": "BTC-IDR" } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | symbol for which all orders should be cancelled |
Cancel Order
Success response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/cancel-order",
"code": 0,
"message": "SUCCESS"
}
Rejected response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1718713055526,
"method": "private/cancel-order",
"code": 7,
"message": "ORDER_NOT_FOUND"
}
The cancel order request reply only confirms whether the cancellation is successfully placed. To check whether the order is actually cancelled or not, detailed order historical information should be checked, or WSS subscription to user.orders channel should be made for listen for updates.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/cancel-order { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/cancel-order", "params": { "symbol": "BTC-IDR", "order_id": "abcdefg-123-abcd-1234-c6ff6de212e2" } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/cancel-order", "params": { "symbol": "BTC-IDR", "order_id": "abcdefg-123-abcd-1234-c6ff6de212e2" } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | symbol for which the order should be cancelled |
order_id | string | yes | exchange generated ID when the order was placed |
Cancel Order List
Success response example
{
"request_id": "4ca9dca1-c8a1-4684-82f5-a02df8ee7241",
"timestamp": 1719308888747,
"method": "private/cancel-order-list",
"code": 0,
"message": "SUCCESS",
"data": {
"results": [
{
"index": 0,
"code": 0,
"message": "SUCCESS"
},
{
"index": 1,
"code": 0,
"message": "SUCCESS"
},
{
"index": 2,
"code": 0,
"message": "SUCCESS"
},
{
"index": 3,
"code": 0,
"message": "SUCCESS"
},
{
"index": 4,
"code": 0,
"message": "SUCCESS"
}
]
}
}
Partial success example
{
"request_id": "ea80dd7f-354e-45a7-a828-0b91f3b38749",
"timestamp": 1719308723061,
"method": "private/cancel-order-list",
"code": 5,
"message": "PARTIAL_SUCCESS",
"reason": "some orders failed to be canceled",
"data": {
"results": [
{
"index": 0,
"code": 0,
"message": "SUCCESS"
},
{
"index": 1,
"code": 0,
"message": "SUCCESS"
},
{
"index": 2,
"code": 0,
"message": "SUCCESS"
},
{
"index": 3,
"code": 0,
"message": "SUCCESS"
},
{
"index": 4,
"code": 7,
"message": "ORDER_NOT_FOUND"
},
{
"index": 5,
"code": 0,
"message": "SUCCESS"
}
]
}
}
The cancel order request reply only confirms whether the cancellation is successfully placed. To check whether the order is actually cancelled or not, detailed order historical information should be checked, or WSS subscription to user.orders channel should be made for listen for updates.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/cancel-order-list { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/cancel-order-list", "params": { "orders": [ { "symbol": "BTC-IDR", "order_id": "abcdefg-123-abcd-1234-c6ff6de212e2" }, { "symbol": "BTC-USDTT", "order_id": "xyzasdf-456-efgh-5678-c6ff6de211k3" }, ... ] } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/cancel-order-list", "params": { "orders": [ { "symbol": "BTC-IDR", "order_id": "abcdefg-123-abcd-1234-c6ff6de212e2" }, { "symbol": "BTC-USDTT", "order_id": "xyzasdf-456-efgh-5678-c6ff6de211k3" }, ... ] } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
orders | array(object) | yes | array of the orders records to be cancelled. Max 10 elements. Each record follows the parameters schema described here |
Response Parameters - Body:
Field | Type | Required | Description |
---|---|---|---|
data.results | 2d-array (object) | yes | result array where each index represents the object that contains the result of the cancellation placement. Below are the object fields |
data.results[index].index | integer | yes | index of the element in request array |
data.results[index].code | integer | yes | cancellation placement execution code |
data.results[index].message | string(enum) | yes | cancellation placement execution message code |
data.results[index].reason | string | no | in case cancellation placement is rejected, reason of the rejection |
Get Account Information
Response example
{
"request_id": "35061da9-6343-4c72-ac20-b228a1456623",
"timestamp": 1719310184322,
"method": "private/get-account-information",
"code": 0,
"message": "SUCCESS",
"data": {
"assets": {
"IDR": {
"balance": "100000000000",
"available": "100000000000",
"order": "0",
"notional": {
"available": "100000000000",
"total": "100000000000",
"currency": "IDR"
}
},
"PTU": {
"balance": "100000000000",
"available": "100000000000",
"order": "0",
"notional": {
"available": "100000000000",
"total": "100000000000",
"currency": "IDR"
}
}
}
}
}
Returns the actual state of the balance for the account that is authorized by respective api_key.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-account-information { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/get-account-information", "params": {} } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-account-information", "params": {} } |
Response Parameters - Body:
Field | Type | Description |
---|---|---|
assets | object | List of all non-zero assets in the wallet in dictionaries. The keys of the dict is the asset name such as "eth", "btc" |
assets.[asset_name].balance | string | Total balance of current asset |
assets.[asset_name].available | string | Available amount to withdraw of current asset |
assets.[asset_name].order | string | Total balance of open orders |
Get Open Orders
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/get-open-orders",
"code": 0,
"message": "SUCCESS",
"data": {
"count": 345,
"orders": [
{
"status": "PARTIALLY_FILLED",
"symbol": "BTC-IDR",
"type": "LIMIT",
"time_in_force": "GTC",
"exec_inst": "POST_ONLY",
"side": "BUY",
"price": "15000",
"size": "2",
"cum_price": "15000",
"cum_size": "0.35",
"cum_value": "5250",
"order_id": "12345678-abcd-efgh-ijkl-1234567890ab",
"client_order_id": "my-order-id-1",
"created_at": 16775774795300,
"updated_at": 16775774797678
},
...
]
}
}
Request the actual status of the order that were is expected to be placed within the last trading day session (within the last 24 hours).
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-open-orders { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462, "method": "private/get-open-orders", "params": { "symbol": "BTC-IDR", "page": 0, "page_size":50, "side":"BUY" } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-open-orders", "params": { "symbol": "BTC-IDR", "page": 0, "page_size": 50, "side":"BUY" } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | no | symbol for which all currently opened orders should be returned |
page | integer | yes | page number (starts from zero) |
page_size | integer | yes | size of a page (default: 20, max: 200) |
side | string | no | side of order [BUY, SELL] |
Response Parameters - The data payload containes the following fields:
Field | Type | Description |
---|---|---|
data.orders | 2d-array (object) | statuses of the orders that were found successfully. See below section for single order status definition |
data.count | integer | number of the open orders found at the moment of the initial (page:0) inquiry submission |
Response Parameters - Single order status defition contains the following fields:
Field | Type | Description |
---|---|---|
status | string(enum) | current order status: PLACED, CANCELED, REJECTED, PARTIALLY_FILLED, FILLED |
reason | string | (optional) only sent for REJECTED order, actual rejection reason as string |
symbol | string | instrument the order is placed for, ex. ‘BTC-IDR’ |
type | string(enum) | order type: MARKET, LIMIT |
time_in_force | string(enum) | order validity instructions: * for Market Orders - empty * for Limit Orders - IOC (immediate-or-cancel) or FOK (fill-or-kill) or GTC (good-till-cancel) |
exec_inst | string(enum) | (for Limit Orders only) - empty or POST_ONLY |
side | string(enum) | BUY or SELL |
price | string | price at which the order was placed. (Limit Order only) |
size | string | original order quantity |
cum_price | string | average price of already filled qty for this order (in case of the partial fill) |
cum_size | string | cumulative filled quantity for this order (in case of the partial fill) |
cum_value | string | cumulative filled quantity in QUOTE currency for this order (in case of the partial fill), ex. for ‘BTC-IDR’ the value will be in IDR |
order_id | string | order id assigned by the Exchange |
client_order_id | string | (optional) client id if assigned by the client while placing the order |
created_at | integer | timestamp(unix milli) of order creation within Exchange |
updated_at | integer | timestamp(unix milli) of the latest update of this order |
Get Order History
Success response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/get-order-history",
"code": 0,
"message": "SUCCESS",
"data": {
"orders": [
{
"status": "PARTIALLY_FILLED",
"symbol": "BTC-IDR",
"type": "LIMIT",
"time_in_force": "GTC",
"exec_inst": "POST_ONLY",
"side": "BUY",
"price": "15000",
"size": "2",
"cum_price": "15000",
"cum_size": "0.35",
"cum_value": "5250",
"order_id": "12345678-abcd-efgh-ijkl-1234567890ab",
"client_order_id": "my-order-id-1",
"created_at": 16775774795300,
"updated_at": 16775774797678
},
...
]
}
}
Error response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/get-order-history",
"code": 7,
"message": "ORDER_NOT_FOUND",
"reason": "Order not found"
}
Retrieve orders that have been placed previously by the client.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-order-history Page and page_size fields usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/get-order-history", "params": { "symbol": "BTC-IDR", "t_start": 1676869976772, "t_end": 1677869976772, "page": 0, "page_size": 50, "status": "FILLED", "side": "BUY" } } Order_ids field usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/get-order-history", "params": { "symbol": "BTC-IDR", "order_ids": [ "aaa-bbb-ccc", ... ], "t_start": 1676869976772, "t_end": 1677869976772, } } |
Websocket | Page and page_size fields usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-order-history", "params": { "symbol": "BTC-IDR", "t_start": 1676869976772, "t_end": 1677869976772, "page": 0, "page_size": 50, "status": "FILLED", "side": "BUY" } } Order_ids field usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-order-history", "params": { "symbol": "BTC-IDR", "client_order_ids": [ "xxx-yyy-zzz", ... ], "t_start": 1676869976772, "t_end": 1677869976772, } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | no | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
t_start | integer | yes | start timestamp(unix milli) - defaults to 24 hours ago if empty (Only support 1 day range) |
t_end | integer | yes | end timestamp(unix milli) - defaults to now if empty (Only support 1 day range) |
page | integer | no | page number (starts from zero) NOTE: if order_ids are set, page value will be omitted |
page_size | integer | no | size of a page (default: 20, max: 200) NOTE: only used in case page field is set |
side | string(enum) | no | side of order [BUY, SELL] |
status | string(enum) | no | current order status: PLACED, CANCELED, REJECTED, PARTIALLY_FILLED, FILLED |
Response Parameters - The data payload containes the following fields:
Field | Type | Description |
---|---|---|
data.orders | 2d-array (object) | statuses of the orders that were found successfully. See below section for single order status definition |
Response Parameters - Single order status definition contains the following fields:
Field | Type | Description |
---|---|---|
status | string(enum) | current order status: PLACED, CANCELED, REJECTED, PARTIALLY_FILLED, FILLED |
reason | string | (optional) only sent for REJECTED order, actual rejection reason as string |
symbol | string | instrument the order is placed for, ex. ‘BTC-IDR’ |
type | string(enum) | order type: MARKET, LIMIT |
time_in_force | string(enum) | order validity instructions: * for Market Orders - empty * for Limit Orders - IOC (immediate-or-cancel) or FOK (fill-or-kill) or GTC (good-till-cancel) |
exec_inst | string(enum) | (for Limit Orders only) - empty or POST_ONLY |
side | string(enum) | BUY or SELL |
price | string | price at which the order was placed. (Limit Order only) |
size | string | original order quantity |
cum_price | string | average price of already filled qty for this order (in case of the partial fill) |
cum_size | string | cumulative filled quantity for this order (in case of the partial fill) |
cum_value | string | cumulative filled quantity in QUOTE currency for this order (in case of the partial fill), ex. for ‘BTC-IDR’ the value will be in IDR |
order_id | string | order id assigned by the Exchange |
client_order_id | string | (optional) client id if assigned by the client while placing the order |
created_at | integer | timestamp(unix milli) of order creation within Exchange |
updated_at | integer | timestamp(unix milli) of the latest update of this order |
Get Order Details
Success response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/get-order-details",
"code": 0,
"message": "SUCCESS",
"data": {
"order_info": {
"status": "PARTIALLY_FILLED",
"symbol": "BTC-IDR",
"type": "LIMIT"
"time_in_force": "GTC",
"exec_inst": "POST_ONLY",
"side": "BUY",
"price": "15000",
"size": "2",
"cum_price": "15000",
"cum_size": "0.35",
"cum_value": "5250",
"order_id": "12345678-abcd-efgh-ijkl-1234567890ab",
"client_order_id": "my-cool-order-id-1",
"created_at": 16775774795300,
"updated_at": 16775774797678
},
"trades_info": [
{
"trade_id": "fake-trade-id-1",
"symbol": "BTC-IDR",
"side": "buy",
"price": "15000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"traded_size": "0.905",
"traded_at": 16775774795500
},
{
"trade_id": "fake-trade-id-2",
"symbol": "BTC-IDR",
"side": "buy",
"price": "15000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"traded_size": "0.755",
"traded_at": 16775774795550
}
]
}
}
Error response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774798300,
"method": "private/get-order-details",
"code": 7,
"message": "ORDER_NOT_FOUND",
"reason": "Order not found"
}
Specific request that retrieves the full detail of the order that was placed by the client. Result reports the order status and, if any, trades that order took part in.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-order-details { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/get-order-details", "params": { "symbol": "BTC-IDR", "order_id": "aaa-bbb-ccc", "t_start": 1676869976772, "t_end": 1677869976772, } } |
Websocket | { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-order-details", "params": { "symbol": "BTC-IDR", "order_id": "xxx-yyy-zzz", "t_start": 1676869976772, "t_end": 1677869976772, } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
order_id | string | required if client_order_id is empty | exchange assigned order id |
client_order_id | string | required if order_id is empty | client order id |
t_start | integer | yes | start timestamp (Only support 1 day range) - unix milli |
t_end | integer | yes | end timestamp (Only support 1 day range) - unix milli |
Response Parameters - The data payload containes the following fields:
Field | Type | Description |
---|---|---|
data.order_info | object | details of the orders that were found successfully. See below section for single order details definition |
data.trades_info | 2d-array (object) | NOTE: only returned in case there were trades done for this order, empty array otherwise |
Response Parameters - Trades Information array element is a simplified version of the detailed Trade information:
Field | Type | Description |
---|---|---|
side | string(enum) | side of order [BUY, SELL] |
symbol | string | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
fee | string | fee related to the trade NOTE: value can be negative in case it’s a rebate |
fee_asset | string | asset of what the deducted fee is based in, consisting either base or quote (example: BTC, IDR, etc.) |
fee_type | string(enum) | source of the fee application [maker, taker] |
trade_id | string | ID of a trade that is generated by Exchange |
price | string | price where order wants to be placed |
traded_size | string | amount in base that has been executed/filled |
traded_at | integer | timestamp(unix milli) of when trade happened |
Get Trade History
Success response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797463,
"method": "private/get-trade-history",
"code": "0",
"message": "SUCCESS",
"data": {
"trades": [
{
"trade_id": "my-trade-id",
"order_id": "my-order-id",
"symbol": "BTC-IDR",
"side": "buy",
"price": "350000000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"client_order_id": "my-client-order-id",
"traded_size": "0.905",
"traded_at": 1676869976772
},
...
]
}
}
Retrieves the full Private Trades information for the specific client’s account.
HTTP & Websocket Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-trade-history Page and page_size fields usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/get-trade-history", "params": { "symbol": "BTC-IDR", "t_start": 16775773797462, "t_end": 16775774797462, "page": 0, "page_size": 50 } } Trade_ids field usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "api_key": "my-key", "signature": "my-signature", "method": "private/get-trade-history", "params": { "trade_ids": [ "a88b9054-bde2-4fd7-8a4e-c6ff6de61138", "a88b9054-bde2-4fd7-8a4e-c6ff6de61139", ... ], "symbol": "BTC-IDR", "t_start": 16775773797462, "t_end": 16775774797462, } } |
Websocket | Page and page_size fields usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-trade-history", "params": { "symbol": "BTC-IDR", "t_start": 16775773797462, "t_end": 16775774797462, "page": 0, "page_size": 50 } } Trade_ids field usage { "request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2", "timestamp": 16775774797462, "method": "private/get-trade-history", "params": { "trade_ids": [ "a88b9054-bde2-4fd7-8a4e-c6ff6de61138", "a88b9054-bde2-4fd7-8a4e-c6ff6de61139", ... ], "symbol": "BTC-IDR", "t_start": 16775773797462, "t_end": 16775774797462, } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
params.symbol | string | no | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
params.trade_ids | array of strings | depends | Identifier of a trade, max size 200 NOTE: omitted in case page field is used |
params.t_start | integer | yes | Start timestamp(unix milli) - defaults to 24 hours ago if empty (Only support 1 day range) |
params.t_end | integer | yes | End timestamp(unix milli) - defaults to now if empty (Only support 1 day range) |
params.page | integer | depends | page number (starts from zero) NOTE: if trade_ids are set, page value will be omitted |
params.page_size | integer | depends | size of a page (default: 20, max: 200) NOTE: only used in case page field is set |
Response Parameters - Single trade definition contains the following fields:
Field | Type | Description |
---|---|---|
trades.[index].trade_id | string | ID of a trade that is generated by Exchange |
trades.[index].order_id | string | ID of an order that is generated by Exchange |
trades.[index].symbol | string | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
trades.[index].side | string(enum) | side of order [BUY, SELL] |
trades.[index].price | string | price where order wants to be placed |
trades.[index].traded_size | string | amount in base that has been executed/filled |
trades.[index].fee | string | fee related to the trade NOTE: value can be negative in case it’s a rebate |
trades.[index].fee_asset | string | asset of what the deducted fee is based in, consisting either base or quote (example: BTC, IDR, etc.) |
trades.[index].fee_type | string(enum) | source of the fee application [maker, taker] |
trades.[index].client_order_id | string | unique key that will be used by clients to identify their orders |
trades.[index].traded_at | integer | timestamp(unix milli) of when trade happened |
Fund Management API
Create Withdrawal
Example request
{
"api_key": "es3jfk6RccWzuJBd",
"method": "private/create-withdrawal",
"params": {
"amount": "420",
"asset": "USDT",
"full_name": "Bartholomew Bumblefizz III",
"network": "Binance Smartchain",
"residential_address": "The Teapot Cottage, 7 ½ Mushroom Lane, Willowbrook Glade, Gnomeville, Middle-earth",
"to_address": "0x919dcAbb830AEc5F63599A3165f89862819601F0",
"to_memo": ""
},
"request_id": "dec3b2d8-02e8-4acb-8a13-f1e7f07d069e",
"signature": "a5a4e0412d3b11882f02fc1c1c3922197663047a600805797253961354f969a3",
"timestamp": 1739352304101
}
Success response example
{
"request_id": "dec3b2d8-02e8-4acb-8a13-f1e7f07d069e",
"timestamp": 1739352304102,
"method": "private/create-withdrawal",
"code": 0,
"message": "SUCCESS",
"data": {
"withdrawal_id": "ec617015-fc8e-4445-9aa9-5785dae507d4",
}
}
Create withdrawal endpoint initiates a process of withdrawing funds to blockchain address. Successful response means request has passed the validation and corresponding amount is locked for withdrawal. Withdrawal will be processed asynchronously and its status can be checked using /v1/private/get-withdrawal-status
endpoint.
HTTP Request
HTTP POST /v1/private/create-withdrawal
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
to_address | string | yes | Address of user’s wallet |
to_memo | string | no | Memo of the transaction |
asset | string (enum) | yes | Type of asset user want to withdraw |
network | string (enum) | yes | Network of the transaction |
amount | string | yes | Amount of asset user want to withdraw |
full_name | string | depends | Full name of the recipient of funds |
residential_address | string | depends | Residential address of the recipient of funds |
travel_rule_id | string | depends | Identifier of a pre-populated travel rule record |
Either travel_rule_id
or full_name
and residential_address
are required to comply with the FATF travel rule regulation. Value for travel_rule_id
can be provided by your Pintu manager.
Response Parameters
Field | Type | Description |
---|---|---|
withdraw_id | string | ID generated by Exchange. User will use this withdraw_id to check the status of the withdrawal |
Confirm withdrawal
Request with TOTP code
{
"request_id":"a88b9054-bde2-4fd7-8a4e-c6ff6de212a6",
"api_key":"HnJYkI8PagKoJz1V",
"signature":"00bb10504a795f10baa64afa63589c1b1ff3cb1416c083ea328e05860eee7970",
"method":"private/confirm-withdrawal",
"params":{
"withdrawal_id":"04e2e210-3718-44bd-95d5-fc336cd77e58",
"authenticator_code":"778899",
},
"timestamp":1738828851868
}
Success response
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212a6",
"timestamp": 1738828854168,
"method": "private/confirm-withdrawal",
"code": 0,
"message": "SUCCESS",
"data": {
"withdrawal_id": "04e2e210-3718-44bd-95d5-fc336cd77e58",
"message": "SUCCESS"
}
}
Depending on user's security settings withdrawal may require OTP confirmation. OTP can be sent to user's email or phone number, or time-based OTP (such as Google Authenticator) can be used.
HTTP Request
HTTP POST /v1/private/confirm-withdrawal
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
withdrawal_id | string | yes | Identifier of withdrawal to confirm |
authenticator_code | string | depends | TOTP authenticator code |
otp_code | string | depends | OTP code (delivered via SMS/Email) |
Either authenticator_code
or otp_code
is required.
Response Parameters
Field | Type | Description |
---|---|---|
withdrawal_id | string | Will return id of the confirmed withdrawal. |
Get Funds Transfer History
Success response example
{
"request_id": "aqab9054-1111-1111-1111-c6ff6de332e5",
"timestamp": 1694595911,
"method": "private/get-funds-transfer-history",
"code": 0,
"message": "SUCCESS",
"data": {
"deposits": [
{
"amount": "20000",
"asset": "IDR",
"type": "DEPOSIT",
"created_at": 1694511704030,
"transact_at": 1694511703615,
"hash": "321987s49hks93812sdf",
"from_address": "",
"to_address": "czx41237cad321da312",
"memo": "",
"network": "Ethereum",
"status": "SUCCESS"
}
],
"withdrawals": [
{
"amount": "10000",
"asset": "IDR",
"fee": "",
"withdrawal_id": "321321a-2222-1111-2222-91212134d47",
"created_at": 1694513832263,
"transact_at": 1694519845526,
"hash": "",
"from_address": "",
"to_address": "",
"to_memo": "",
"network": "",
"status": "SUCCESS"
}
]
}
}
HTTP Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-funds-transfer-history { "request_id": "aqab9054-bde2-4fd7-8a4e-c6ff11e212e5", "api_key": "my-key", "signature": "my-signature", "method": "private/get-funds-transfer-history", "params": { "status":"SUCCESS", "type":"WITHDRAWAL, DEPOSIT", "page":1, "page_size":"20, "from": 1676869976772, "to": 1677869976772 } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
type | string (enum) | yes | type of transaction, DEPOSIT or WITHDRAWAL |
status | string (enum) | yes | status of the fund. INIT, SUCCESS, FAILED - will return all if empty |
page | int | no | page number (starts from zero) |
page_size | timestamp | yes | size of a page (default: 20, max: 200) |
from | timestamp | yes | start timestamp (unix milli) - defaults to 24 hours ago if empty (Only support 1 day range) |
to | timestamp | yes | end timestamp (unit milli) - defaults to now if empty (Only support 1 day range) |
Response Parameters
Field | Type | Description |
---|---|---|
deposits | array of object | Array of deposits |
withdrawals | array of object | Array of withdrawals |
Response Parameters - deposits
Field | Type | Description |
---|---|---|
amount | string | Amount of the transaction |
asset | string | Asset of the transaction |
type | string (enum) | Type of deposit |
created_at | timestamp | Timestamp of the transaction in exchange (unix milli) |
transact_at | timestamp | Timestamp of the transaction on chain (unix milli) |
hash | string | Hash of the transaction |
from_address | string | From address of the transaction (For internal transaction address will be Pintu Pro or something else) |
to_address | string | To address of the transaction |
memo | string | Memo of the transaction |
network | string (enum) | Network of the deposit taken place |
status | string (enum) | status of the request. SUCCESS, FAILED |
Response Parameters - withdrawals
Field | Type | Description |
---|---|---|
amount | string | Amount of the withdrawal request |
asset | string (enum) | Asset of the transaction |
fee | string | Fee of the withdrawal transaction |
withdrawal_id | string | ID generated by Exchange. User will use this withdraw_id to check the status of the withdrawal |
created_at | timestamp | Timestamp of the request (unix milli) |
transact_at | timestamp | Timestamp of the transaction on chain (unix milli) |
hash | string | Hash of the transaction |
from_address | string | Address of the receiver’s wallet |
to_address | string | Address of the user’s wallet |
to_memo | string | Memo of the transaction |
network | string (enum) | Network of the deposit taken place |
status | string (enum) | status of the request. INIT, SUCCESS, FAILED |
Get Withdrawal Status
Success response example
{
"request_id": "a88b9054-bde2-1111-2222-c6ff6de212e1",
"timestamp": 1694596244,
"method": "private/get-withdrawal-status",
"code": 0,
"message": "SUCCESS",
"data": {
"amount": "0.0001",
"fee": "0.000005",
"withdraw_id": "5630a62e-6c89-2222-1111-6b5087dde0e9",
"created_at": 1694596165484,
"updated_at": 1694596166128,
"transact_at": 0,
"to_address": "3123123123asdasdasdas312312",
"to_memo": "",
"status": "INIT"
}
}
HTTP Request
Protocol | Body |
---|---|
HTTP POST | /v1/private/get-withdrawal-status { "request_id": "a88b9054-2222-3333-1111-c6ff6de212e2", "api_key": "my-api-key", "signature": "my-signature", "timestamp": 16775774797462 "method": "private/get-withdrawal-status", "params": { "withdraw_id": "b751483e-1111-2222-1111-fe8889954d59" } } |
Request Parameters
Field | Type | Description |
---|---|---|
withdraw_id | string | ID generated by Exchange. User will use this withdraw_id to check the status of the withdrawal |
Response Parameters
Field | Type | Description |
---|---|---|
amount | string | Amount of the withdrawal request |
fee | string | Fee of the withdrawal transaction |
withdraw_id | string | ID generated by Exchange. User will use this withdraw_id to check the status of the withdrawal |
created_at | timestamp | Timestamp of the request |
updated_at | timestamp | ID generated by Exchange. User will use this withdraw_id to check the status of the withdrawal |
transact_at | timestamp | Transaction of the withdrawal happen on chain |
to_address | string | Address of the user’s wallet |
to_memo | string | Memo of the transaction |
status | string (enum) | status of the withdrawal: INIT,SUCCESS,FAILED |
Get Deposit Addresses
Success response example
{
"request_id": "a88b9054-bde2-2222-1111-c6ff6de212e4",
"timestamp": 1691631580,
"method": "private/get-deposit-addresses",
"code": 0,
"message": "SUCCESS",
"data": {
"deposit_addresses": [
{
"address": "3123123dasdasda32131212",
"asset": "BTC",
"memo": "user_memo",
"network": "Bitcoin"
}
]
}
}
HTTP Request
Protocol | Body |
---|---|
HTTP POST | /private/get-deposit-addresses { "request_id": "a88b9054-2222-1111-3333-c6ff6de212e4", "api_key": "my-api-key", "signature": "my-signature", "method":"private/get-deposit-addresses", "params": { "asset": "BTC" } } |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
asset | string (enum) | yes | Type of asset. Will return all if empty |
Response Parameters
Field | Type | Description |
---|---|---|
addresses | array of object | Array of deposit addresses |
Response Parameters - Each address contains:
Field | Type | Description |
---|---|---|
address | string | Address to deposit |
asset | string (enum) | Type of asset user want to deposit |
memo | string | Memo of the address |
network | string (enum) | Network of the address |
Get Network Reference
Success response example
{
"timestamp": 1694595267,
"method": "public/get-network-reference",
"code": 0,
"message": "SUCCESS",
"data": {
"networks": [
{
"asset": "BTC",
"name": "Bitcoin",
"fee": "0.0005"
}
]
}
}
HTTP Request
Protocol | Body |
---|---|
HTTP GET | /v1/public/get-network-reference?asset=BTC |
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
asset | string (enum) | yes | Type of asset |
Response Parameters
Field | Type | Description |
---|---|---|
networks | array of object | list of networks in the dictionary. The keys of the dictionary is the token name such as IDR, SOL, BTC, and ETH |
Response Parameters - Each network contains:
Field | Type | Description |
---|---|---|
name | string (enum) | Name of the network |
asset | string (enum) | Type of asset |
fee | string | Withdrawal fee |
Private Websocket Subscriptions
User Balance Snapshot
Stream data record example
{
"timestamp": 1676869976772,
"method": "subscription",
"channel": "user.balance.snapshot",
"data": {
"assets": {
"btc": {
"balance": "10",
"available": "8",
"order": "2"
},
"eth": {
"balance": "32",
"available": "30",
"order": "2",
},
...
}
}
}
Channel: user.balance
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"method": "subscribe",
"params": {
"channels": ["user.balance.snapshot"]
}
}
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
assets | object | List of all non-zero assets in the wallet in dictionaries. The keys of the dict is the asset name such as "eth", "btc" |
assets.[asset_name].balance | string | Total balance of current asset |
assets.[asset_name].available | string | Available amount to withdraw of current asset |
assets.[asset_name].order | string | Total asset currently in open order |
User Orders per symbol
Stream data record example
{
"timestamp": 1676869976772,
"method": "subscription",
"channel": "user.orders.BTC-IDR",
"data": {
"orders": [
{
"status": "PARTIALLY_FILLED",
"symbol": "BTC-IDR",
"type": "LIMIT"
"time_in_force": "GTC",
"exec_inst": "POST_ONLY",
"side": "BUY",
"price": "15000",
"size": "2",
"cum_price": "15000",
"cum_size": "0.35",
"cum_value": "5250",
"order_id": "12345678-abcd-efgh-ijkl-1234567890ab",
"client_order_id": "my-cool-order-id-1",
"created_at": 16775774795300,
"updated_at": 16775774797678
},
...
]
}
}
Unsubscribe response example (in case of multiple channels)
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976772,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.orders.BTC-IDR"
}
}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976775,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.orders.ETH-IDR",
}
}
This is a private API, which requires authorization fields to be provided on the body. See this page for reference.
Channel: user.orders.{symbol}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "subscribe", // subscribe
"params": {
"channels": [
"user.orders.BTC-IDR",
...
]
}
}
Unsubscription Request
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "unsubscribe", // unsubscribe
"params": {
"channels": [
"user.orders.BTC-IDR",
"user.orders.ETH-IDR",
...
]
}
}
NOTE: in case unsubscribe request contains multiple channels in it’s payload, the client should expect one response message per channel in return
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.orders | 2d-array (object) | statuses of the orders that were found successfully. See below section for single order status definition |
Streaming Reply - Single order status definition contains the following fields:
Field | Type | Description |
---|---|---|
status | string(enum) | current order status: PLACED, CANCELED, REJECTED, PARTIALLY_FILLED, FILLED |
reason | string | (optional) only sent for REJECTED order, actual rejection reason as string |
symbol | string | instrument the order is placed for, ex. ‘BTC-IDR’ |
type | string(enum) | order type: MARKET, LIMIT |
time_in_force | string(enum) | order validity instructions: * for Market Orders - empty * for Limit Orders - IOC (immediate-or-cancel) or FOK (fill-or-kill) or GTC (good-till-cancel) |
exec_inst | string(enum) | (for Limit Orders only) - empty or POST_ONLY |
side | string(enum) | BUY or SELL |
price | string | price at which the order was placed. (Limit Order only) |
size | string | original order quantity |
cum_price | string | average price of already filled qty for this order (in case of the partial fill) |
cum_size | string | cumulative filled quantity for this order (in case of the partial fill) |
cum_value | string | cumulative filled quantity in QUOTE currency for this order (in case of the partial fill), ex. for ‘BTC-IDR’ the value will be in IDR |
order_id | string | order id assigned by the Exchange |
client_order_id | string | (optional) client id if assigned by the client while placing the order |
created_at | integer | timestamp(unix milli) of order creation within Exchange |
updated_at | integer | timestamp(unix milli) of the latest update of this order |
User Orders (all symbols)
Stream data record example
{
"timestamp": 1676869976772,
"method": "subscription",
"channel": "user.orders",
"data": {
"orders": [
{
"status": "PARTIALLY_FILLED",
"symbol": "BTC-IDR",
"type": "LIMIT"
"time_in_force": "GTC",
"exec_inst": "POST_ONLY",
"side": "BUY",
"price": "15000",
"size": "2",
"cum_price": "15000",
"cum_size": "0.35",
"cum_value": "5250",
"order_id": "12345678-abcd-efgh-ijkl-1234567890ab",
"client_order_id": "my-cool-order-id-1",
"created_at": 16775774795300,
"updated_at": 16775774797678
},
...
]
}
}
Unsubscribe response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976772,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.orders"
}
}
This is a private API, which requires authorization fields to be provided on the body. See this page for reference.
Channel: user.orders
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "subscribe", // subscribe
"params": {
"channels": [
"user.orders",
...
]
}
}
Unsubscription Request
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "unsubscribe", // unsubscribe
"params": {
"channels": [
"user.orders",
"user.orders.ETH-IDR",
...
]
}
}
NOTE: in case unsubscribe request contains multiple channels in it’s payload, the client should expect one response message per channel in return
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.orders | 2d-array (object) | statuses of the orders that were found successfully. See below section for single order status definition |
Streaming Reply - Single order status definition contains the following fields:
Field | Type | Description |
---|---|---|
status | string(enum) | current order status: PLACED, CANCELED, REJECTED, PARTIALLY_FILLED, FILLED |
reason | string | (optional) only sent for REJECTED order, actual rejection reason as string |
symbol | string | instrument the order is placed for, ex. ‘BTC-IDR’ |
type | string(enum) | order type: MARKET, LIMIT |
time_in_force | string(enum) | order validity instructions: * for Market Orders - empty * for Limit Orders - IOC (immediate-or-cancel) or FOK (fill-or-kill) or GTC (good-till-cancel) |
exec_inst | string(enum) | (for Limit Orders only) - empty or POST_ONLY |
side | string(enum) | BUY or SELL |
price | string | price at which the order was placed. (Limit Order only) |
size | string | original order quantity |
cum_price | string | average price of already filled qty for this order (in case of the partial fill) |
cum_size | string | cumulative filled quantity for this order (in case of the partial fill) |
cum_value | string | cumulative filled quantity in QUOTE currency for this order (in case of the partial fill), ex. for ‘BTC-IDR’ the value will be in IDR |
order_id | string | order id assigned by the Exchange |
client_order_id | string | (optional) client id if assigned by the client while placing the order |
created_at | integer | timestamp(unix milli) of order creation within Exchange |
updated_at | integer | timestamp(unix milli) of the latest update of this order |
User Trades per symbol
Stream data record example
{
"timestamp": 1672304484978,
"method": "subscription",
"channel": "user.trades.BTC-IDR",
"data": {
"trades": [
{
"trade_id": "fake-trade-id-2",
"order_id": "aaa-bbb-ccc-2",
"symbol": "BTC-IDR",
"side": "buy",
"price": "351000000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"traded_size": "0.105",
"client_order_id": "xxx-yyy-zzz-2",
"traded_at": 1676869976772
},
...
{
"trade_id": "fake-trade-id-1",
"order_id": "aaa-bbb-ccc-1",
"symbol": "BTC-IDR",
"side": "buy",
"price": "350000000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"traded_size": "0.905",
"client_order_id": "xxx-yyy-zzz-1",
"traded_at": 1676869976760
}
]
}
}
Unsubscribe response example (in case of multiple channels)
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976772,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.trades.BTC-IDR"
}
}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976775,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.trades.ETH-IDR",
}
}
This is a private API, which requires authorization fields to be provided on the body. See this page for reference.
NOTE: the order of the elements in the trades array is by traded_at field, where most recent message comes first. This way some parsing level optimizations (re reaction time) can be possible on the client side.
Channel: user.trades.{symbol}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "subscribe", // subscribe
"params": {
"channels": [
"user.trades.BTC-IDR",
...
]
}
}
Unsubscription Request
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "unsubscribe", // unsubscribe
"params": {
"channels": [
"user.trades.BTC-IDR",
"user.trades.ETH-IDR",
...
]
}
}
NOTE: in case unsubscribe request contains multiple channels in it’s payload, the client should expect one response message per channel in return.
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.trades | array | Updates on trades happened since last message |
Streaming Reply - Single trade definition contains the following fields:
Field | Type | Description |
---|---|---|
trades.[index].trade_id | string | ID of a trade that is generated by Exchange |
trades.[index].order_id | string | ID of an order that is generated by Exchange |
trades.[index].symbol | string | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
trades.[index].side | string(enum) | side of order [BUY, SELL] |
trades.[index].price | string | price where order wants to be placed |
trades.[index].traded_size | string | amount in base that has been executed/filled |
trades.[index].fee | string | fee related to the trade NOTE: value can be negative in case it’s a rebate |
trades.[index].fee_asset | string | asset of what the deducted fee is based in, consisting either base or quote (example: BTC, IDR, etc.) |
trades.[index].fee_type | string(enum) | source of the fee application [maker, taker] |
trades.[index].client_order_id | string | unique key that will be used by clients to identify their orders |
trades.[index].traded_at | integer | timestamp(unix milli) of when trade happened |
User Trades (all symbols)
Stream data record example
{
"timestamp": 1672304484978,
"method": "subscription",
"channel": "user.trades",
"data": {
"trades": [
{
"trade_id": "fake-trade-id-2",
"order_id": "aaa-bbb-ccc-2",
"symbol": "BTC-IDR",
"side": "buy",
"price": "351000000",
"fee": "0.001",
"fee_asset": "BTC",
"fee_type": "maker",
"traded_size": "0.105",
"client_order_id": "xxx-yyy-zzz-2",
"traded_at": 1676869976772
},
...
{
"trade_id": "fake-trade-id-1",
"order_id": "aaa-bbb-ccc-1",
"symbol": "SOL-IDR",
"side": "buy",
"price": "350000000",
"fee": "0.001",
"fee_asset": "SOL",
"fee_type": "maker",
"traded_size": "0.905",
"client_order_id": "xxx-yyy-zzz-1",
"traded_at": 1676869976760
}
]
}
}
Unsubscribe response example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1676869976772,
"method": "unsubscribe",
"code": "OK",
"message": "Success",
"data": {
"channel": "user.trades"
}
}
This is a private API, which requires authorization fields to be provided on the body. See this page for reference.
NOTE: the order of the elements in the trades array is by traded_at field, where most recent message comes first. This way some parsing level optimizations (re reaction time) can be possible on the client side.
Channel: user.trades.{symbol}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "subscribe", // subscribe
"params": {
"channels": [
"user.trades,
...
]
}
}
Unsubscription Request
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "unsubscribe", // unsubscribe
"params": {
"channels": [
"user.trades",
"user.trades.ETH-IDR",
...
]
}
}
NOTE: in case unsubscribe request contains multiple channels in it’s payload, the client should expect one response message per channel in return.
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.trades | array | Updates on trades happened since last message |
Streaming Reply - Single trade definition contains the following fields:
Field | Type | Description |
---|---|---|
trades.[index].trade_id | string | ID of a trade that is generated by Exchange |
trades.[index].order_id | string | ID of an order that is generated by Exchange |
trades.[index].symbol | string | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |
trades.[index].side | string(enum) | side of order [BUY, SELL] |
trades.[index].price | string | price where order wants to be placed |
trades.[index].traded_size | string | amount in base that has been executed/filled |
trades.[index].fee | string | fee related to the trade NOTE: value can be negative in case it’s a rebate |
trades.[index].fee_asset | string | asset of what the deducted fee is based in, consisting either base or quote (example: BTC, IDR, etc.) |
trades.[index].fee_type | string(enum) | source of the fee application [maker, taker] |
trades.[index].client_order_id | string | unique key that will be used by clients to identify their orders |
trades.[index].traded_at | integer | timestamp(unix milli) of when trade happened |
Public Websocket Subscriptions
Orderbook Snapshot
Stream data record example
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 1672304484978,
"method": "subscription",
"channel": "aggrbook.snapshot.10.BTC-USDT",
"data": {
"symbol": "BTC-USDT",
"bids": [
...,
[
"16493.50",
"0.006",
"100",
],
[
"16493.00",
"0.100",
"87",
]
],
"asks": [
[
"16611.00",
"0.029",
"124",
],
[
"16612.00",
"0.213",
"90",
],
...,
]
}
}
Channel: aggrbook.snapshot.{depth}.{symbol}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"method": "subscribe",
"params": {
"channels": ["aggrbook.snapshot.{depth}.{symbol}"]
}
}
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | Symbol name |
depth | integer | no | The depth (number of price levels) of the market data book. Default is 1 for level 1 order book (quotes). Valid values are 1 or 10. |
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.symbol | string | Symbol name |
data.bids | array (string) | Price levels ordered by descending by price. Each price level is three elements array of decimals. Bids array: [0] = Price, [1] = Quantity, [2] = Number of Orders |
data.asks | array (string) | Price levels ordered by descending by price. Each price level is three elements array of decimals. Bids array: [0] = Price, [1] = Quantity, [2] = Number of Orders |
Trades
Stream data record example
{
"timestamp": 1672304484978,
"method": "subscription",
"channel": "trades.BTC-USDT",
"data":
"trades": [
{
"side": "SELL",
"price": "51327.500000",
"size": "0.000100",
"timestamp": 1613581138462,
"symbol": "BTC-USDT"
}
]
}
}
Channel: trades.{symbol}
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"method": "subscribe",
"params": {
"channels": ["trades.{symbol}"]
}
}
Unsubscription Request
{
"request_id": "a88b9054-bde2-4fd7-8a4e-c6ff6de212e2",
"timestamp": 16775774797462,
"api_key": "my-api-key",
"signature": "my-signature",
"method": "unsubscribe", // unsubscribe
"params": {
"channels": [
"user.trades.BTC-IDR",
"user.trades.ETH-IDR",
...
]
}
}
Request Parameters
Field | Type | Required | Description |
---|---|---|---|
symbol | string | yes | Symbol name |
Streaming Reply - Channel update contains the following fields:
Field | Type | Description |
---|---|---|
data.trades | array | Updates on trades happened since last message |
Streaming Reply - Single trade definition contains the following fields:
Field | Type | Description |
---|---|---|
trades.[index].side | string | Side of the taker order (buy or sell) |
trades.[index].price | string | Trade price |
trades.[index].size | string | Trade quantity |
trades.[index].timestamp | integer | Trade timestamp(unix milli) |
trades.[index].symbol | string | Symbol name (example: BTC-IDR, ETH-IDR, etc.) |