Skip to main content

General Info

REST Basic Info

  • The REST base URL referenced in this document: https://api-sepolia.p99.world/api/v1 (testnet).
  • All endpoint responses are JSON.
  • All times and timestamps are UNIX time. Spot endpoints use seconds unless explicitly noted as ts ending in milliseconds (the public-trade websocket push and GET /spot/trades ts field are milliseconds — the only millisecond-precision timestamps in the spot API).
  • All numeric amounts (prices, balances, quantities) are returned as strings to preserve precision.

Authentication

/spot/* and /admin/spot/* endpoints sit behind the project-wide auth middleware. Three schemes are accepted:

SchemeHeaderUse for
Bearer JWTAuthorization: Bearer <JWT>All /spot/* endpoints (read + write).
API Key (HMAC-SHA256)X-MBX-APIKEY: <api_key> + ?timestamp=<ms>&signature=<hex>All /spot/* endpoints except POST /spot/transfer and POST /spot/withdraw/request (those reject API-key callers with 403 API Key permission denied).
Admin API KeyX-API-Key: <ADMIN_API_KEY>All /admin/spot/* endpoints.

GET /wallet/tokens is public (no auth required). All GET /spot/* market-data endpoints (/spot/markets, /spot/depth, /spot/trades, /spot/klines, /spot/ticker/24hr, /spot/health) are public too.

HMAC Signing

The HMAC scheme is Binance-compatible:

payload = query_string_without_signature + body_string
signature = hex( HMAC_SHA256(secret_key, payload) )
final_url = ${BASE}${PATH}?<query>&timestamp=<ms>&signature=<hex>
  • timestamp is in milliseconds, must be within ±5000 ms of server time.
  • For GET / DELETE: parameters go in the query string, body is empty.
  • For POST: timestamp goes in the query string, parameters in a JSON body. The signature payload is timestamp=<ms> concatenated with the raw JSON body bytes.

See POST /api-keys for issuing user API keys (uses the perp-side endpoint; the keys returned work for spot too).

Endpoint Conventions

  • For GET / DELETE endpoints, parameters must be sent in the query string.
  • For POST endpoints, parameters are sent in a JSON body. The timestamp query parameter (HMAC scheme) is the only thing in the query string for these.
  • There is no requirement for parameter ordering.
  • Symbol matching is case-sensitive — use DFUSDT, not dfusdt.

Response Envelope

GET /wallet/tokens uses the project-standard envelope:

{ "success": true, "data": [...], "error": null, "timestamp": 1778312000 }

The other spot endpoints currently return data directly (bare object / array) on success. Errors are {"error": "<STRING_CODE>"} plus the relevant HTTP status.

HTTP Return Codes

StatusMeaning
200Success.
400Request validation or engine pre-check failed. Body has error with a string code (see Error Codes).
401Auth failed: missing / invalid JWT, missing / wrong HMAC signature, or expired timestamp.
403Forbidden: API-key calling a JWT-only endpoint, or addressing another user's resource.
404Resource not found (or hidden because it belongs to another user).
409Conflict: market in halted status.
410Gone: market in delisted status.
503Engine unavailable: spot trading disabled, ENGINE_BUSY (mpsc backlog full), or ENGINE_RESTARTING (recovery in progress). Transient — retry with backoff.
500Server fault: usually DB_ERROR.

Rate Limits

  • No per-user weight limits are enforced today (MVP). Plan for ~50 req/s per user across all /spot/* endpoints.
  • The matching engine has an internal mpsc backlog; if it fills, place / cancel / status return 503 ENGINE_BUSY. Retry with exponential backoff (200 ms → 400 ms → 800 ms, max 5 retries).

Conventions in this Documentation

  • Each endpoint page lists HTTP method + path, auth scheme(s), request parameters (with type & whether required), a response example, and a cURL + Python snippet.
  • Parameter types: STRING, NUMBER, DECIMAL (string-encoded for precision), BOOL, LONG (unix timestamp).
  • Order amounts shown in examples assume the testnet DFUSDT market (tick_size=0.0001, lot_size=0.01, min_notional=1).