Skip to main content

List Withdrawals

Description​

Returns the authenticated user's withdrawal history, ordered most-recent first. Results can be filtered by status.

For a description of each status value, see Withdrawal Status. For the full withdrawal flow, see Withdraw Flow.

HTTP Request​

GET /spot/withdrawals (JWT or API Key)

Weight​

0 — no per-IP weight limit today (MVP).

Request Parameters​

NameTypeRequiredDescription
statusENUMNOFilter by withdrawal status. One of signed, confirmed, expired. See Withdrawal Status. Omit to return all statuses.
limitNUMBERNONumber of records to return. Default 50, max 200 (clamped server-side).

status and limit are the only supported filters — there is no token, start, or end parameter.

Response Example​

200 OK

[
{
"id": "9f2a1c4e-5b67-4d8a-bf93-2e1f4a6c8d10",
"token": "DF",
"amount": "100",
"amount_in_wei": "100000000000000000000",
"fee": "0",
"chain_id": 97,
"nonce": 42,
"status": "confirmed",
"backend_signature": "0x...65-byte hex...",
"expiry": 1778402000,
"tx_hash": "0xabc123...",
"block_number": 106400000,
"created_at": 1778315530,
"confirmed_at": 1778316040
}
]
FieldNotes
idWithdrawal UUID. Use with GET /spot/withdrawals/:id to fetch a single record.
tokenToken symbol — DF in MVP.
amountDecimal string of the requested amount.
amount_in_weiWei-scaled (base-units) amount that was placed in the EIP-712 value field. Feed this into vault.withdraw() when submitting a stuck signed row from history.
feeWithdrawal fee (decimal string). Currently always "0".
chain_idTarget chain id — 97 (BSC Testnet).
nonceEIP-712 per-(user, chain) nonce.
statussigned / confirmed / expired. See Withdrawal Status.
backend_signature0x-prefixed 65-byte EIP-712 signature the backend issued for this withdrawal. null if no signature is stored.
expiryUnix seconds — the EIP-712 signature validity cutoff (the deadline field of the signed message).
tx_hashOn-chain transaction hash. null until status = confirmed.
block_numberBlock number of the SpotWithdrawal event. null until status = confirmed.
created_atUnix seconds — when the backend signed the release message.
confirmed_atUnix seconds — when the listener observed the on-chain event. null until confirmed.

Error Responses​

HTTPerror
401(empty body) — missing or invalid credential.
500internal — unexpected database error.

Full list: Error Codes.

Code Examples​

cURL (JWT)​

JWT="your_jwt_token"

# All withdrawals
curl -s "https://api-sepolia.ztdx.io/api/v1/spot/withdrawals" \
-H "Authorization: Bearer ${JWT}"

# Filter by status
curl -s "https://api-sepolia.ztdx.io/api/v1/spot/withdrawals?status=signed" \
-H "Authorization: Bearer ${JWT}"

cURL (HMAC API Key)​

API_KEY="your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(date +%s%3N)
QUERY="status=confirmed&timestamp=${TIMESTAMP}"
SIGNATURE=$(echo -n "${QUERY}" | openssl dgst -sha256 -hmac "${API_SECRET}" | awk '{print $2}')

curl -s \
-H "X-MBX-APIKEY: ${API_KEY}" \
"https://api-sepolia.ztdx.io/api/v1/spot/withdrawals?${QUERY}&signature=${SIGNATURE}"

Python​

import time, hmac, hashlib, requests

API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
BASE_URL = "https://api-sepolia.ztdx.io/api/v1"

def signed_get(path: str, params: dict) -> list:
ts = int(time.time() * 1000)
# Build the EXACT query string we'll sign and send (order matters)
full_params = {**params, "timestamp": ts}
qs = "&".join(f"{k}={v}" for k, v in full_params.items())
sig = hmac.new(API_SECRET.encode(), qs.encode(), hashlib.sha256).hexdigest()
r = requests.get(
f"{BASE_URL}{path}?{qs}&signature={sig}",
headers={"X-MBX-APIKEY": API_KEY},
timeout=5,
)
r.raise_for_status()
return r.json()

withdrawals = signed_get("/spot/withdrawals", {"status": "confirmed", "limit": 20})
for w in withdrawals:
print(
f" {w['id'][:8]}... {w['token']} {w['amount']:>14} "
f"status={w['status']} created_at={w['created_at']}"
)