Python
A complete signed-request client and a few common workflows.
import time
import hmac
import hashlib
import requests
import uuid
from urllib.parse import urlencode
API_KEY = "zd_84444a6e..."
SECRET = "073CuVWk..."
BASE_URL = "https://api.zetariumdex.com"
def sign(secret: str, query_string: str) -> str:
return hmac.new(secret.encode(), query_string.encode(), hashlib.sha256).hexdigest()
def signed_request(method: str, path: str, params: dict | None = None, body: dict | None = None):
params = dict(params or {})
params["timestamp"] = int(time.time() * 1000)
# Build the canonical query string (sorted, URL-encoded; signature is appended afterwards).
sorted_items = sorted(params.items())
query_string = urlencode(sorted_items)
signature = sign(SECRET, query_string)
url = f"{BASE_URL}{path}?{query_string}&signature={signature}"
headers = {"X-API-KEY": API_KEY}
if body is not None:
headers["Content-Type"] = "application/json"
return requests.request(method, url, headers=headers, json=body)
# 1. Read futures balance
resp = signed_request("GET", "/v2/futures/balance")
print(resp.json())
# 2. Place an idempotent LIMIT BUY
client_order_id = str(uuid.uuid4())
resp = signed_request(
"POST",
"/v2/orders",
body={
"symbol": "BTCUSDT",
"side": "BUY",
"type": "LIMIT",
"quantity": "0.001",
"price": "30000",
"clientOrderId": client_order_id,
},
)
print(resp.json())
# 3. Retry the same order — should be idempotent
resp2 = signed_request(
"POST",
"/v2/orders",
body={
"symbol": "BTCUSDT",
"side": "BUY",
"type": "LIMIT",
"quantity": "0.001",
"price": "30000",
"clientOrderId": client_order_id,
},
)
assert resp2.json().get("idempotent") is True
# 4. Close an open position
resp = signed_request(
"POST",
"/v2/positions/close",
body={"positionId": "cmod1234..."},
)
print(resp.json())