Public market data needs no key. Everything that touches an account is a signed request made with an API key, which acts only for the account that created it — and can trade, but never withdraw.
| GET | /venue | What this venue is: state, custody, assets it holds, whether it trades. |
| GET | /exchangeInfo | Every market's rules: tick, lot, minimum, maker and taker fee. |
| GET | /allticker | Last price and 24 h statistics for every market. |
| GET | /depth?symbol=BTCUSDT | The order book. |
| GET | /trades?symbol=BTCUSDT | Recent public trades. |
| GET | /kline?symbol=BTCUSDT&interval=60 | Candles (interval in seconds). |
| GET | /audit | What the venue says it owes, for solvency checks. |
The signature covers the method, the full path with its query, and a hash of the exact body bytes. The nonce is the request time: it must be within 30 seconds of the server clock and is accepted once per key, so a captured request can neither be replayed nor given a different body.
nonce = current time in unix milliseconds, as a string
body_hash = hex(sha256(raw request body)) # sha256("") for an empty body
canonical = f"{nonce}:{METHOD}:{path_with_query}:{body_hash}"
signature = hex(hmac_sha256(secret, canonical))
Headers:
X-ACCESS-KEY: <your key's public id>
X-ACCESS-NONCE: <nonce>
X-ACCESS-SIGN: <signature>
path_with_query is the full path, e.g. /api/v1/private/trade/limitTrading keys are mandates: your wallet signs their markets, largest order, order value per 24 hours and expiry on the mandate console, and the secret is shown once. A key made without a wallet signature is read-only.
| POST | /private/user | Your balances. |
| POST | /private/trade/limit | Place a limit order: market, side (1 sell, 2 buy), amount, price, post_only. |
| POST | /private/trade/market | Place a market order: market, side, amount. IOC inside a 5% band. |
| POST | /private/trade/cancel | Cancel one of your orders: market, order_id. |
| POST | /private/trade/cancel_batch | Cancel up to 100 of your orders: market, orders [ids]. |
| POST | /private/order/pending | Your open orders (all markets, or one). |
| POST | /private/order/finished | Your finished orders, by time range. |
| POST | /private/order/pending/detail | One of your open orders: market, order_id. |
| POST | /private/order/finished/detail | One of your finished orders: order_id. |
| POST | /private/order/deals | The fills of one of your orders: order_id. |
Order ids are UUID strings. A body that includes a user_id other than your own is refused with 403. Order fields are required — a missing price is an error, never a default.
| 400 | Refused: invalid field, price off the tick, amount off the lot or below the minimum, insufficient balance, post-only would cross. | |
| 401 | Signature missing or wrong, nonce stale (±30 s) or already used, key unknown or IP not allowed. | |
| 403 | The request names another account (a key acts only for its own), or the order falls outside the key's mandate: market, largest order, 24-hour order value, expiry. Read-only keys cannot trade. | |
| 404 | Not found — including someone else's order, which answers exactly like a missing one. | |
| 410 | A retired endpoint. | |
| 429 | Over the key's budget: 40 requests burst, 10 per second sustained. | |
| 503 | Paused for a security review. Balances are unaffected. |
Every API call is signed over its method, path, query and body hash. The nonce is the request time, accepted within 30 seconds and once per key: a captured request cannot be replayed or given a different body.
The account comes from the credential, never from the request. A request naming another account is refused, not ignored.
Each key has its own request budget. A runaway agent slows down; it does not take the venue, or anyone else's orders, with it.
Moving value off the venue takes the owner's own wallet signature over the exact amount and destination. No API key can do it.
A key the owner's wallet signs into existence, naming its markets, its largest order, its order value per 24 hours and its expiry. The venue enforces every line on every order; the owner revokes it in one click.
Quote, place, cancel and read history as Model Context Protocol tools. The tool set is fixed and versioned with the release — never assembled from data.
Evaluate an order — fees, limits, mandate budget — without placing it. Retry any write with the same key and it happens once.
Anything a third party can write — asset names, listing text, support replies — arrives in typed fields marked untrusted, never inside instructions or tool descriptions.
Treat anything another party can write — asset names, listing text, support replies — as data, never as instructions to your agent. How mandates work