Some endpoints will require an API Key. Please register here to obtain an API key.
The API key is viewable in the Profile -> API section.
Never share your API key/secret key to ANYONE.
The API is designed to be compatible with the Binance V3 API. If you have client code to use the Binance V3 API, then most features will work on this API without modification other than the base endpoint and API keys.
For any questions in sudden drop in performance with the API and/or Websockets.
For any questions on your code implementation with the API and/or Websockets.
For any general questions about the API not covered in the documentation.
For cases such as missing funds, help with 2FA, etc.
General Info
General API Information
The base endpoint is: https://app.quote.trade/api
All http POST and PUT endpoints expects a minified JSON. ({} if there
is no data to send.)
For GET endpoints, parameters must be sent in the query string.
For POST and PUT endpoints, the parameters must be sent
as the
request body with content type
application/json.
All http endpoints return either a minified JSON object or a minified JSON array.
HTTP Return Codes
HTTP 200 return code is used for success or business reject responses.
HTTP 4XX return codes are used for malformed requests;
the issue is on the sender's side.
HTTP 403 return code is used when the WAF Limit (Web Application Firewall) has been
violated.
HTTP 409 return code is used when a cancelReplace order partially succeeds. (e.g. if the
cancellation of the order fails but the new order placement succeeds.)
HTTP 429 return code is used when breaking a request rate limit.
HTTP 418 return code is used when an IP has been auto-banned for continuing to send
requests after receiving 429 codes.
HTTP 5XX return codes are used for internal errors; the issue is on
quote.trade's side.
It is important to NOT treat this as a failure operation; the execution status is
UNKNOWN and could have been a success.
Error Codes and Messages
If there is an error, the API will return an error with a message of the reason.
The error payload on API is as follows:
{"error":"Invalid symbol."}
LIMITS
IP Limits
Each route has a weight which determines for the number of requests each endpoint counts
for. Heavier endpoints and endpoints that do operations on multiple symbols will have a heavier
weight.
When a 429 is received, it's your obligation as an API to back off and not spam the API.
Repeatedly violating rate limits and/or failing to back off after receiving 429s will result in
an automated IP ban (HTTP status 418).
IP bans are tracked and scale in duration for repeat offenders, from 2 minutes
to 3 days.
A Retry-After header is sent with a 418 or 429 responses and will give the number
of seconds required to wait, in the case of a 429, to prevent a ban, or, in the case of a 418,
until the ban is over.
The limits on the API are based on the IPs, not the API keys.
Websocket Limits
WebSocket connections have a limit of 5 incoming messages per second. A message is considered:
A PING frame
A PONG frame
A JSON controlled message (e.g. subscribe, unsubscribe)
A connection that goes beyond the limit will be disconnected; IPs that are repeatedly disconnected may
be banned.
A single connection can listen to a maximum of 1024 streams.
API Limit Introduction
The /api/* endpoints adopt either of two access limiting rules, IP
limits or UID (account) limits.
Endpoints related to /api/*:
According to the two modes of IP and UID (account) limit, each are independent.
Endpoints share the 1200 per minute limit based on IP.
Data Sources
The API system is asynchronous, so some delay in the response is normal and expected.
Each endpoint has a data source indicating where the data is being retrieved, and thus which endpoints
have the most up-to-date response.
These are the three sources, ordered by which is has the most up-to-date response to the one with potential
delays in updates.
Matching Engine - the data is from the matching Engine
Memory - the data is from a server's local or external memory
Database - the data is taken directly from a database
Endpoint security type
Each endpoint has a security type that determines how you will
interact with it. This is stated next to the NAME of the endpoint.
If no security type is stated, assume the security type is NONE.
API-keys are passed into the Rest API via the X-MBX-APIKEY
header.
API-keys and secret-keys are case sensitive.
By default, API-keys can access all secure routes.
Security Type
Description
NONE
Endpoint can be accessed freely.
TRADE
Endpoint requires sending a valid API-Key and signature.
USER_DATA
Endpoint requires sending a valid API-Key and signature.
USER_STREAM
Endpoint requires sending a valid API-Key.
MARKET_DATA
Endpoint requires sending a valid API-Key.
TRADE, and USER_DATA endpoints are
SIGNED endpoints.
SIGNED (TRADE, AND USER_DATA )
Endpoint security
SIGNED endpoints require an additional parameter, signature, to be
sent in the http headers.
Endpoints use HMAC SHA256 signatures. The HMAC SHA256 signature is a keyed
HMAC SHA256 operation.
Use your secretKey as the key and request body as the value for the HMAC
operation.
The signature is not case sensitive.
SIGNED Endpoint Examples for POST /api/order
Here is a step-by-step example of how to send a valid signed payload from the
Linux command line using echo, openssl, and curl.
These terms will be used throughout the documentation, so it is recommended especially for new users to read
to help their understanding of the API.
base asset refers to the asset that is the quantity of a symbol. For the
symbol BTC/USDC, BTC would be the base asset.
quote asset refers to the asset that is the price of a symbol. For the symbol
BTC/USDC, USDC would be the quote asset.
ENUM definitions
Symbol status (status):
PRE_TRADING
TRADING
POST_TRADING
END_OF_DAY
HALT
AUCTION_MATCH
BREAK
Account and Symbol Permissions (permissions):
SPOT
MARGIN
LEVERAGED
TRD_GRP_002
TRD_GRP_003
TRD_GRP_004
TRD_GRP_005
Order status (status):
Status
Description
NEW
The order has been accepted by the engine.
PARTIALLY_FILLED
A part of the order has been filled.
FILLED
The order has been completed.
CANCELED
The order has been canceled by the user.
PENDING_CANCEL
Currently unused
REJECTED
The order was not accepted by the engine and not processed.
EXPIRED
The order was canceled according to the order type's rules (e.g. LIMIT FOK orders with no fill,
LIMIT IOC or MARKET orders that partially fill) or by the exchange, (e.g. orders canceled during
liquidation, orders canceled during maintenance)
OCO Status (listStatusType):
Status
Description
RESPONSE
This is used when the ListStatus is responding to a failed action. (E.g. Orderlist placement or
cancellation)
EXEC_STARTED
The order list has been placed or there is an update to the order list status.
ALL_DONE
The order list has finished executing and thus no longer active.
OCO Order Status (listOrderStatus):
Status
Description
EXECUTING
Either an order list has been placed or there is an update to the status of the list.
ALL_DONE
An order list has completed execution and thus no longer active.
REJECT
The List Status is responding to a failed action either during order placement or order canceled.)
Order types (orderTypes, type):
LIMIT
MARKET
STOP_LOSS
STOP_LOSS_LIMIT
TAKE_PROFIT
TAKE_PROFIT_LIMIT
LIMIT_MAKER
Order Response Type (newOrderRespType):
ACK
RESULT
FULL
Order side (side):
BUY
SELL
Time in force (timeInForce):
This sets how long an order will be active before expiration.
Status
Description
GTC
Good Til Canceled An order will be on the book unless the order is canceled.
IOC
Immediate Or Cancel An order will try to fill the order as much as it can before the order
expires.
FOK
Fill or Kill An order will expire if the full order cannot be filled upon execution.
Kline/Candlestick chart intervals:
s-> seconds; m -> minutes; h -> hours; d -> days; w -> weeks; M -> months
1s
1m
3m
5m
15m
30m
1h
2h
4h
6h
8h
12h
1d
3d
1w
1M
User Registration
Code:
const { Wallet, verifyMessage } = require("ethers"); // ethers.js version 6.13.5
const privateKey = "0x"; // Replace with your actual private key
const wallet = new Wallet(privateKey);
/**
* Signs a message with the given private key.
* @param {string} challenge - The challenge text received from the server.
* @returns {Promise} - The signed message.
*/
async function signMessage(challenge) {
const signature = await wallet.signMessage(challenge);
return signature;
}
Request Data:
{
"signature": "{ecrecover signature generated in step 2}",
"challenge": "{CHALLENGE TEXT received in step 1}"
}
Send a HTTP POST request to the following API with the Ethereum wallet address:
API URL:
https://app.quote.trade/api/getChallenge
Request Data:
{ "login": "{ETHEREUM_WALLET_ADDRESS}" }
Response: Extract the challenge text from the response:
{ "challenge": "{CHALLENGE_TEXT}" }
Generate a ecrecover signature for the challenge text.
Use the Ethereum wallet's private key to sign the challenge text received in step 1. The resulting
signature
will be used for the registration request.
The following code demonstrates how to generate the ecrecover signature using the ethers.js library.
Call the Register User API
Send a HTTP POST request to the following API with the necessary data:
API URL:
https://app.quote.trade/api/registerUser
{ "signature": "{ecrecover signature generated in step 2}", "challenge": "{CHALLENGE
TEXT received in step 1}" }
Response: Extract the requestToken and requestSecret from the
API
response:
const { Wallet, verifyMessage } = require("ethers"); // ethers.js version 6.13.5
const privateKey = "0x"; // Replace with your actual private key
const wallet = new Wallet(privateKey);
/**
* Signs a message with the given private key.
* @param {string} challenge - The challenge text received from the server.
* @returns {Promise} - The signed message.
*/
async function signMessage(challenge) {
const signature = await wallet.signMessage(challenge);
return signature;
}
To authenticate a user, follow these steps:
Pre-requisites
Already registered Ethereum wallet address.
Access to the wallet's private key.
Steps
Get the challenge text
Send a HTTP POST request to the following API with the Ethereum wallet address:
API URL:
https://app.quote.trade/api/getChallenge
Request Data:
{ "login": "{ETHEREUM_WALLET_ADDRESS}" }
Response: Extract the challenge text from the response:
{ "challenge": "{CHALLENGE_TEXT}" }
Generate a ecrecover signature for the challenge text.
Use the Ethereum wallet's private key to sign the challenge text received in step 1. The resulting
signature
will be used for the registration request.
The following code demonstrates how to generate the ecrecover signature using the ethers.js library.
Call the Register User API
Send a HTTP POST request to the following API with the necessary data:
API URL: https://app.quote.trade/api/logon
Request Data:
{ "signature": "{ecrecover signature generated in step 2}", "challenge": "{CHALLENGE
TEXT received in step 1}" }
Response: Extract the requestToken and requestSecret from the
API
response: