Endpoints — Overview
Conventions, default base URL, and a copy-pasteable signed-request client in six languages.
Conventions
- Base URL —
https://api.zetariumdex.com. - Version prefix —
/v2/. - Content type — JSON only. All bodies and responses are
application/json. - Decimals — sent and returned as strings to avoid precision loss. Example:
"quantity": "0.001". - Symbols — uppercase, no separator. Example:
"BTCUSDT","ETHUSDT". - Timestamps — Unix epoch in milliseconds.
- Side —
BUY|SELL. - Order type —
LIMIT|MARKET|STOP|STOP_MARKET|TAKE_PROFIT|TAKE_PROFIT_MARKET. - Position side —
BOTH|LONG|SHORT. UseBOTHin one-way mode; useLONG/SHORTin hedge mode. - Order status —
NEW|PARTIALLY_FILLED|FILLED|CANCELED|REJECTED|PENDING_NEW.
Sections
| Group | Description |
|---|---|
| Account | Balance, positions, exposure, transfers, PnL series, the /v2/me/* trader-stats family (/me/stats, /me/funding-history, /me/trades, /me/rebate-tier, /me/earnings, /me/rebate/* and /me/bd/* claim flows). |
| Trading | Place / cancel orders, batch, close positions, list orders, MyTrades, positionHistory. |
| Futures Configuration | Leverage, margin mode, atomic close-and-switch-margin, position mode. |
| Market Data | Public — symbols, ticker, depth, klines, trades, leaderboard. |
| API Key Management | List and revoke keys (UI-mirrored). |
| Known Limitations | MAKER fill visibility, missing GET counterparts, edit-order workaround, TP/SL pairing, WebSocket auto-subscribe behavior. |
Client setup
Drop-in signed-request helpers in six languages. Every per-endpoint
Example in this section assumes you have the helper for your language
loaded — it handles timestamp, alphabetical sort, HMAC-SHA256, and the
X-API-KEY header for you.
Replace API_KEY and SECRET with the values you copied during
onboarding. The helper accepts optional
params (sent as the query string, included in the signature) and an
optional JSON body (sent separately, not signed — TLS provides body
integrity).
# ~/.zdexrc
export API_KEY="zd_84444a6e..."
export SECRET="073CuVWk..."
export BASE_URL="https://api.zetariumdex.com"
# Sign function — call as: SIG=$(sign "$SECRET" "$QUERY")
sign() {
echo -n "$2" | openssl dgst -sha256 -hmac "$1" -binary | xxd -p -c 256
}cURL examples below are written inline so you can read the full request
on one line. For endpoints with extra query parameters, sort them
alphabetically together with timestamp before signing.
// zdex.mjs — Node 18+ (built-in fetch & crypto)
import crypto from 'node:crypto';
const API_KEY = process.env.API_KEY;
const SECRET = process.env.SECRET;
const BASE_URL = 'https://api.zetariumdex.com';
export async function signedRequest(method, path, { params = {}, body } = {}) {
const all = { ...params, timestamp: Date.now() };
const qs = Object.keys(all)
.sort()
.map((k) => `${encodeURIComponent(k)}=${encodeURIComponent(all[k])}`)
.join('&');
const sig = crypto.createHmac('sha256', SECRET).update(qs).digest('hex');
const headers = { 'X-API-KEY': API_KEY };
if (body) headers['Content-Type'] = 'application/json';
const res = await fetch(`${BASE_URL}${path}?${qs}&signature=${sig}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
return res.json();
}# zdex.py — requires `requests`
import time, hmac, hashlib, requests
from urllib.parse import urlencode
API_KEY = "zd_84444a6e..."
SECRET = "073CuVWk..."
BASE_URL = "https://api.zetariumdex.com"
def signed_request(method: str, path: str, params: dict | None = None, body: dict | None = None):
p = dict(params or {})
p["timestamp"] = int(time.time() * 1000)
qs = urlencode(sorted(p.items()))
sig = hmac.new(SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
headers = {"X-API-KEY": API_KEY}
if body is not None:
headers["Content-Type"] = "application/json"
return requests.request(
method,
f"{BASE_URL}{path}?{qs}&signature={sig}",
headers=headers,
json=body,
)// zdex.go
package zdex
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"sort"
"time"
)
const (
APIKey = "zd_84444a6e..."
Secret = "073CuVWk..."
BaseURL = "https://api.zetariumdex.com"
)
func SignedRequest(method, path string, params map[string]string, body any) ([]byte, error) {
if params == nil {
params = map[string]string{}
}
params["timestamp"] = fmt.Sprintf("%d", time.Now().UnixMilli())
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
v := url.Values{}
for _, k := range keys {
v.Set(k, params[k])
}
qs := v.Encode()
mac := hmac.New(sha256.New, []byte(Secret))
mac.Write([]byte(qs))
sig := hex.EncodeToString(mac.Sum(nil))
var bodyReader io.Reader
if body != nil {
b, _ := json.Marshal(body)
bodyReader = bytes.NewReader(b)
}
u := fmt.Sprintf("%s%s?%s&signature=%s", BaseURL, path, qs, sig)
req, err := http.NewRequest(method, u, bodyReader)
if err != nil {
return nil, err
}
req.Header.Set("X-API-KEY", APIKey)
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
return io.ReadAll(res.Body)
}// zdex.rs — Cargo.toml: reqwest, hmac, sha2, hex, serde_json, tokio
use hmac::{Hmac, Mac};
use sha2::Sha256;
use serde_json::Value;
use std::time::{SystemTime, UNIX_EPOCH};
type HmacSha256 = Hmac<Sha256>;
const API_KEY: &str = "zd_84444a6e...";
const SECRET: &str = "073CuVWk...";
const BASE_URL: &str = "https://api.zetariumdex.com";
pub async fn signed_request(
method: reqwest::Method,
path: &str,
params: &[(&str, &str)],
body: Option<&Value>,
) -> reqwest::Result<Value> {
let ts = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
.to_string();
let mut all: Vec<(&str, String)> = params.iter().map(|(k, v)| (*k, v.to_string())).collect();
all.push(("timestamp", ts));
all.sort_by(|a, b| a.0.cmp(b.0));
let qs: String = all
.iter()
.map(|(k, v)| format!("{}={}", urlencoding::encode(k), urlencoding::encode(v)))
.collect::<Vec<_>>()
.join("&");
let mut mac = HmacSha256::new_from_slice(SECRET.as_bytes()).unwrap();
mac.update(qs.as_bytes());
let sig = hex::encode(mac.finalize().into_bytes());
let url = format!("{BASE_URL}{path}?{qs}&signature={sig}");
let mut req = reqwest::Client::new()
.request(method, &url)
.header("X-API-KEY", API_KEY);
if let Some(b) = body {
req = req.json(b);
}
req.send().await?.json().await
}<?php
// zdex.php — requires php-curl
const API_KEY = 'zd_84444a6e...';
const SECRET = '073CuVWk...';
const BASE_URL = 'https://api.zetariumdex.com';
function signed_request(string $method, string $path, array $params = [], ?array $body = null): array {
$params['timestamp'] = (int)(microtime(true) * 1000);
ksort($params);
$qs = http_build_query($params);
$sig = hash_hmac('sha256', $qs, SECRET);
$url = BASE_URL . $path . "?{$qs}&signature={$sig}";
$headers = ['X-API-KEY: ' . API_KEY];
if ($body !== null) $headers[] = 'Content-Type: application/json';
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $body !== null ? json_encode($body) : null,
]);
return json_decode(curl_exec($ch), true);
}