ZetariumZetariumDex

Endpoints — Overview

Conventions, default base URL, and a copy-pasteable signed-request client in six languages.

Conventions

  • Base URLhttps://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.
  • SideBUY | SELL.
  • Order typeLIMIT | MARKET | STOP | STOP_MARKET | TAKE_PROFIT | TAKE_PROFIT_MARKET.
  • Position sideBOTH | LONG | SHORT. Use BOTH in one-way mode; use LONG/SHORT in hedge mode.
  • Order statusNEW | PARTIALLY_FILLED | FILLED | CANCELED | REJECTED | PENDING_NEW.

Sections

GroupDescription
AccountBalance, 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).
TradingPlace / cancel orders, batch, close positions, list orders, MyTrades, positionHistory.
Futures ConfigurationLeverage, margin mode, atomic close-and-switch-margin, position mode.
Market DataPublic — symbols, ticker, depth, klines, trades, leaderboard.
API Key ManagementList and revoke keys (UI-mirrored).
Known LimitationsMAKER 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);
}

On this page