API Reference — Anboto Trading API v2.0#
Download OpenAPI spec · AsyncAPI (WebSocket) spec
Authentication#
Endpoints marked ApiKeyAuth need four headers on every request:
| Header | ||
|---|---|---|
X-API-KEY |
required | your API key |
X-TIMESTAMP |
required | milliseconds since epoch |
X-SIGN |
required | signature, standard Base64 |
X-RECV-WINDOW |
request validity in ms, default 5000 |
Signing. Build timestamp + api_key + recv_window + (queryString | jsonBody) — query string in alphabetical key order, exactly as sent. Base64-decode the secret (standard Base64 if it contains +, / or ends with =, otherwise URL-safe). Sign with HMAC-SHA256 (system-generated keys) or RSA-SHA256 (self-generated keys). X-SIGN is the standard Base64 of the signature, not hex. Keys: pro.anboto.xyz/settings/api.
Every sample on this site calls signed_headers(body) / signed_headers_query(params) — the helper for each language, HMAC variant:
BASE=https://api.pro.anboto.xyz
# signed_headers "<query-or-body string>" -> prints curl -H flags
signed_headers() {
local ts=$(($(date +%s) * 1000))
local key_hex=$(printf '%s' "$API_SECRET" | base64 -d | xxd -p -c 256)
local sign=$(printf '%s' "${ts}${API_KEY}5000$1" \
| openssl dgst -sha256 -mac HMAC -macopt "hexkey:$key_hex" -binary | base64)
printf -- '-H "X-API-KEY: %s" -H "X-TIMESTAMP: %s" -H "X-RECV-WINDOW: 5000" -H "X-SIGN: %s"' \
"$API_KEY" "$ts" "$sign"
}
# GET: curl "$BASE/api/v2/trading/balance?exchange=BINANCE" $(signed_headers "exchange=BINANCE")
# POST: curl -X POST "$BASE/api/v2/trading/order/create" $(signed_headers "$body") \
# -H "Content-Type: application/json" -d "$body"
import base64, hashlib, hmac, json, time
import requests
BASE = "https://api.pro.anboto.xyz"
RECV_WINDOW = "5000"
def _secret_bytes(secret: str) -> bytes:
if any(c in secret for c in "+/") or secret.endswith("="):
return base64.b64decode(secret)
return base64.urlsafe_b64decode(secret + "=" * (-len(secret) % 4))
def _headers(payload: str) -> dict:
ts = str(int(time.time() * 1000))
digest = hmac.new(_secret_bytes(API_SECRET),
(ts + API_KEY + RECV_WINDOW + payload).encode(), hashlib.sha256).digest()
return {"X-API-KEY": API_KEY, "X-TIMESTAMP": ts, "X-RECV-WINDOW": RECV_WINDOW,
"X-SIGN": base64.b64encode(digest).decode()}
def signed_headers(body: dict) -> dict: # POST: sign the JSON body you send
return {**_headers(json.dumps(body)), "Content-Type": "application/json"}
def signed_headers_query(params: dict) -> dict: # GET: sign the sorted query string
return _headers("&".join(f"{k}={v}" for k, v in sorted(params.items())))
use base64::{engine::general_purpose::STANDARD, Engine};
use hmac::{Hmac, Mac};
use reqwest::header::HeaderMap;
use sha2::Sha256;
const BASE: &str = "https://api.pro.anboto.xyz";
fn headers(payload: &str) -> HeaderMap {
let ts = chrono::Utc::now().timestamp_millis().to_string();
let key = STANDARD.decode(std::env::var("API_SECRET").unwrap()).unwrap();
let mut mac = Hmac::<Sha256>::new_from_slice(&key).unwrap();
mac.update(format!("{ts}{}5000{payload}", std::env::var("API_KEY").unwrap()).as_bytes());
let sign = STANDARD.encode(mac.finalize().into_bytes());
let mut h = HeaderMap::new();
h.insert("X-API-KEY", std::env::var("API_KEY").unwrap().parse().unwrap());
h.insert("X-TIMESTAMP", ts.parse().unwrap());
h.insert("X-RECV-WINDOW", "5000".parse().unwrap());
h.insert("X-SIGN", sign.parse().unwrap());
h
}
fn signed_headers(payload: &serde_json::Value) -> HeaderMap { headers(&payload.to_string()) }
fn signed_headers_query(params: &std::collections::BTreeMap<&str, &str>) -> HeaderMap {
headers(¶ms.iter().map(|(k, v)| format!("{k}={v}")).collect::<Vec<_>>().join("&"))
}
const BASE = "https://api.pro.anboto.xyz"
func headers(payload string) map[string]string {
ts := strconv.FormatInt(time.Now().UnixMilli(), 10)
key, _ := base64.StdEncoding.DecodeString(os.Getenv("API_SECRET"))
mac := hmac.New(sha256.New, key)
mac.Write([]byte(ts + os.Getenv("API_KEY") + "5000" + payload))
return map[string]string{
"X-API-KEY": os.Getenv("API_KEY"),
"X-TIMESTAMP": ts,
"X-RECV-WINDOW": "5000",
"X-SIGN": base64.StdEncoding.EncodeToString(mac.Sum(nil)),
}
}
func signedHeaders(body string) map[string]string { return headers(body) }
func signedHeadersQuery(q url.Values) map[string]string {
keys := make([]string, 0, len(q))
for k := range q { keys = append(keys, k) }
sort.Strings(keys)
parts := make([]string, 0, len(keys))
for _, k := range keys { parts = append(parts, k+"="+q.Get(k)) }
return headers(strings.Join(parts, "&"))
}
static final String BASE = "https://api.pro.anboto.xyz";
static HttpRequest.Builder signed(String path, String payload) throws Exception {
String ts = Long.toString(System.currentTimeMillis());
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.getDecoder().decode(apiSecret), "HmacSHA256"));
String sign = Base64.getEncoder().encodeToString(
mac.doFinal((ts + apiKey + "5000" + payload).getBytes(StandardCharsets.UTF_8)));
return HttpRequest.newBuilder(URI.create(BASE + path))
.header("X-API-KEY", apiKey).header("X-TIMESTAMP", ts)
.header("X-RECV-WINDOW", "5000").header("X-SIGN", sign);
}
static HttpRequest signedPost(String path, String jsonBody) throws Exception {
return signed(path, jsonBody).header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();
}
static HttpRequest signedGet(String pathWithQuery) throws Exception { // query keys sorted
String query = pathWithQuery.contains("?") ? pathWithQuery.substring(pathWithQuery.indexOf('?') + 1) : "";
return signed(pathWithQuery, query).GET().build();
}
import { createHmac } from "node:crypto";
const BASE = "https://api.pro.anboto.xyz";
function headers(payload: string): Record<string, string> {
const ts = Date.now().toString();
const sign = createHmac("sha256", Buffer.from(process.env.API_SECRET!, "base64"))
.update(ts + process.env.API_KEY + "5000" + payload).digest("base64");
return { "X-API-KEY": process.env.API_KEY!, "X-TIMESTAMP": ts, "X-RECV-WINDOW": "5000", "X-SIGN": sign };
}
export const signedHeaders = (body: unknown) =>
({ ...headers(JSON.stringify(body)), "Content-Type": "application/json" });
export const signedHeadersQuery = (params: Record<string, string>) =>
headers(Object.keys(params).sort().map((k) => `${k}=${params[k]}`).join("&"));
const val BASE = "https://api.pro.anboto.xyz"
fun signed(path: String, payload: String): HttpRequest.Builder {
val ts = System.currentTimeMillis().toString()
val mac = Mac.getInstance("HmacSHA256").apply {
init(SecretKeySpec(Base64.getDecoder().decode(apiSecret), "HmacSHA256"))
}
val sign = Base64.getEncoder().encodeToString(mac.doFinal((ts + apiKey + "5000" + payload).toByteArray()))
return HttpRequest.newBuilder(URI.create(BASE + path))
.header("X-API-KEY", apiKey).header("X-TIMESTAMP", ts)
.header("X-RECV-WINDOW", "5000").header("X-SIGN", sign)
}
fun signedPost(path: String, jsonBody: String): HttpRequest =
signed(path, jsonBody).header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build()
fun signedGet(pathWithQuery: String): HttpRequest = // query keys sorted
signed(pathWithQuery, pathWithQuery.substringAfter('?', "")).GET().build()
const std::string BASE = "https://api.pro.anboto.xyz";
cpr::Header headers(const std::string& payload) {
std::string ts = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count());
std::string key = base64_decode(std::getenv("API_SECRET"));
std::string msg = ts + std::getenv("API_KEY") + "5000" + payload;
unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int len = 0;
HMAC(EVP_sha256(), key.data(), key.size(),
reinterpret_cast<const unsigned char*>(msg.data()), msg.size(), digest, &len);
return cpr::Header{{"X-API-KEY", std::getenv("API_KEY")}, {"X-TIMESTAMP", ts},
{"X-RECV-WINDOW", "5000"}, {"X-SIGN", base64_encode(digest, len)}};
}
cpr::Header signedHeaders(const std::string& body) { return headers(body); }
cpr::Header signedHeadersQuery(const std::map<std::string, std::string>& params) { // std::map = sorted
std::string qs;
for (auto& [k, v] : params) qs += (qs.empty() ? "" : "&") + k + "=" + v;
return headers(qs);
}
import { createHmac } from "node:crypto";
const BASE = "https://api.pro.anboto.xyz";
function headers(payload) {
const ts = Date.now().toString();
const sign = createHmac("sha256", Buffer.from(process.env.API_SECRET, "base64"))
.update(ts + process.env.API_KEY + "5000" + payload).digest("base64");
return { "X-API-KEY": process.env.API_KEY, "X-TIMESTAMP": ts, "X-RECV-WINDOW": "5000", "X-SIGN": sign };
}
export const signedHeaders = (body) =>
({ ...headers(JSON.stringify(body)), "Content-Type": "application/json" });
export const signedHeadersQuery = (params) =>
headers(Object.keys(params).sort().map((k) => `${k}=${params[k]}`).join("&"));
Ready-made payloads: Request examples. Full clients: github.com/anbotolabs/examples.
Trading#
| Endpoint | ||
|---|---|---|
| GET | /api/v2/trading/balance |
Get balance |
| GET | /api/v2/trading/listenKey |
Listen key |
| GET | /api/v2/trading/order/byId |
Get orders |
| POST | /api/v2/trading/order/cancel |
Cancel order |
| GET | /api/v2/trading/order/cancelAll |
Cancel all open orders |
| POST | /api/v2/trading/order/cancelMany |
Cancel many |
| POST | /api/v2/trading/order/create |
Create order |
| POST | /api/v2/trading/order/createMany |
Create many orders |
| POST | /api/v2/trading/order/create_multiLegs |
Create multi legs order |
| POST | /api/v2/trading/order/createMany/multilegs |
Create many multi legs orders |
| GET | /api/v2/trading/order/find |
Find orders |
| GET | /api/v2/trading/order/open |
Get open orders |
| GET | /api/v2/trading/position |
Get position |
| GET | /api/v2/trading/userTrades |
Get user trades |
Market data#
| Endpoint | ||
|---|---|---|
| GET | /api/v2/data/exchanges |
Exchanges |
| GET | /api/v2/data/fundingRateHistory |
Funding rate history |
| GET | /api/v2/data/instruments |
Instruments |
| GET | /api/v2/data/lastFundingRates |
Last funding rates |
Status#
| Endpoint | ||
|---|---|---|
| GET | /status/ping |
Status |
WebSocket streams#
WebSocket overview — endpoints, listenKey auth, keep-alive, subscribe format.
| Topic | ||
|---|---|---|
| WS | position |
position |
| WS | balance |
balance |
| WS | order |
order |
| WS | trade |
trade |
| WS | child_order |
child_order |
| WS | position_risk |
position_risk |
| WS | ticker |
ticker |
| WS | ohlcv |
ohlcv |
| WS | open_interest |
open_interest |
| WS | Keep-alive (ping/pong) |
Keep-alive (ping/pong) |
Schemas#
All request/response objects: Schemas