Error Codes
Spot APIs return errors as {"error": "<STRING_CODE>"} plus the HTTP status. This page lists every code emitted by the spot subsystem grouped by category.
Auth & permission
| HTTP | error | When |
|---|---|---|
401 | (empty body) | Missing / invalid JWT, missing / wrong HMAC signature, or timestamp outside ±5000 ms of server time. |
403 | API Key permission denied | API-key caller hit POST /spot/transfer or POST /spot/withdraw/request (JWT only). |
403 | FORBIDDEN | Targeted resource (order, withdrawal) belongs to another user. |
Market state
| HTTP | error | When |
|---|---|---|
404 | MARKET_NOT_FOUND | symbol doesn't exist in spot_markets. |
409 | MARKET_HALTED | Market in halted status; no new orders. |
410 | MARKET_DELISTED | Market in delisted status; terminal. |
Order placement (POST /spot/orders)
| HTTP | error | When |
|---|---|---|
400 | invalid side | side not in sell. |
400 | invalid type | type not in market. |
400 | invalid tif | tif not in post_only. Note: lowercase only. |
400 | quantity required for limit | limit order missing quantity. |
400 | quantity required for market sell | market SELL missing quantity. |
400 | quote_quantity required for market buy | market BUY missing quote_quantity. |
400 | INVALID_TICK | price is not a multiple of the market's tick_size. |
400 | INVALID_LOT | quantity is not a multiple of the market's lot_size. |
400 | BELOW_MIN_NOTIONAL | price * quantity < min_notional. |
400 | INSUFFICIENT_BALANCE | The lock the order needs (base for SELL, quote for BUY) exceeds caller's available. |
400 | POST_ONLY_REJECT | tif=post_only order would have crossed the book at placement. |
400 | SELF_TRADE | New order would cross caller's own resting order (DECLINE_TAKER policy). |
Order management
| HTTP | error | When |
|---|---|---|
400 | invalid id | Path :id is not a UUID. |
404 | ORDER_NOT_FOUND | Order doesn't exist, is terminal, or belongs to another user. |
404 | WITHDRAWAL_NOT_FOUND | Withdrawal id doesn't exist or belongs to another user. |
Engine availability
| HTTP | error | When | Action |
|---|---|---|---|
503 | spot trading disabled | SPOT_TRADING_ENABLED=false on this server. | Permanent for this env. |
503 | ENGINE_BUSY | Engine mpsc backlog full. | Retry with backoff (200 / 400 / 800 ms). |
503 | ENGINE_RESTARTING | Recovery in progress. | Retry after a few seconds. |
503 | TICKER_NOT_FOUND | GET /spot/ticker/24hr?symbol=… for a symbol with no row yet. | Will resolve after the first fill. |
Transfer (POST /spot/transfer)
| HTTP | error | When |
|---|---|---|
400 | INVALID_DIRECTION | direction not in spot_to_perp. |
400 | AMOUNT_NON_POSITIVE | amount <= 0. |
400 | INSUFFICIENT_BALANCE | Source side does not have enough free USDT. |
400 | UNSUPPORTED_TOKEN | MVP supports USDT only. |
Withdraw (POST /spot/withdraw/request)
| HTTP | error | When |
|---|---|---|
400 | AMOUNT_NON_POSITIVE | amount <= 0. |
400 | INSUFFICIENT_BALANCE | available < amount for the requested token. |
400 | UNSUPPORTED_TOKEN | Token not in the spot wallet's supported list (currently DF). |
503 | SIGNER_UNAVAILABLE | Backend signer (or its KMS) is unreachable. Transient. |
Admin (/admin/spot/*)
| HTTP | error | When |
|---|---|---|
400 | INVALID_STATUS | status not in delisted. |
400 | AMOUNT_NON_POSITIVE | Credit amount is <= 0. |
404 | DISABLED | POST /admin/spot/balances/credit called when TESTNET_ONLY != true. |
409 | MARKET_EXISTS | Creating a market whose id already exists. |
500 | DB_ERROR | Postgres error during the admin write. |
Server faults
| HTTP | error | When |
|---|---|---|
500 | DB_ERROR | Any unexpected Postgres error during a write. Investigate logs. |
500 | (html body) | Panic in the request task. Capture the request and report. |