{
"error": {
"code": "MACHINE_READABLE_CODE",
"message": "Human readable explanation"
}
}error.code, never on error.message. Messages are written for people and can be reworded.VALIDATION_ERROR adds details, telling you exactly which field failed:{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid request",
"details": [{ "path": "quantity", "message": "Required" }] } }INTERNAL adds a requestId. Quote it when you contact support:{ "error": { "code": "INTERNAL", "message": "Internal server error",
"requestId": "01J9X2K7Qv..." } }| Status | code | What it means | What to do |
|---|---|---|---|
401 | INVALID_API_KEY | No key matches X-MG-API-KEY | Check the header value for typos and stray whitespace |
401 | INVALID_SIGNATURE | The digest did not match, or the header is missing | Work through the checklist below |
401 | INVALID_TIMESTAMP | Outside the receive window, unreadable, missing, or a window above 60000 ms | Sync your clock. Use milliseconds |
401 | REPLAYED_REQUEST | This exact signature was already used inside its window | Re-sign with a fresh timestamp. Never resend identical signed bytes |
403 | INVALID_ORIGIN | Your Origin or Referer does not match the key's domain, or you sent neither | Send Origin: <your registered domain> on every request |
403 | API_PERMISSION_DENIED | The key lacks this route's permission | See the permissions table in section 07 |
403 | API_KEY_DISABLED | An administrator disabled the key | Contact support. Only an administrator can restore it |
403 | KYC_REQUIRED | The account has not completed identity verification | Finish verification in the web app, then retry. No code change is needed |
429 | RATE_LIMIT_EXCEEDED | You passed the per-key rate limit | Back off. See section 07 |
| Status | code | What it means |
|---|---|---|
400 | MALFORMED_JSON | The body is not valid JSON |
400 | VALIDATION_ERROR | The body or query failed schema validation. Read details |
404 | NOT_FOUND | Unknown route, or a resource that is not yours |
409 | CONFLICT | Duplicate resource |
409 | IDEMPOTENCY_IN_PROGRESS | The original request with this Idempotency-Key is still running |
413 | PAYLOAD_TOO_LARGE | The body is over 32 KB |
429 | RATE_LIMITED | The global per-IP limit, which is separate from RATE_LIMIT_EXCEEDED |
500 | INTERNAL | A server fault. Quote requestId to support |
| Status | code | Where | What it means |
|---|---|---|---|
409 | INSUFFICIENT_BALANCE | Spot | Not enough spendable balance to reserve. Nothing was written |
409 | INSUFFICIENT_MARGIN | Futures | Not enough in the futures wallet |
409 | MARGIN_MODE_CONFLICT | Futures | An open position on this symbol already uses the other margin mode |
429 | TOO_MANY_OPEN_ORDERS | Spot | 200 orders are already open on this symbol. Retrying will not help. Cancel one |
400 | ORDER_ALREADY_TERMINAL | Cancel | The order already finished and cannot be cancelled |
501 | CANCEL_NOT_SUPPORTED | Spot cancel | This market runs on the internal matching engine, which has no cancel endpoint. The order stays open and may still fill |
409 | CANCEL_REJECTED_BY_VENUE | Spot cancel | The exchange answered and refused. details.venueCode carries its own code. Retrying will fail identically |
503 | VENUE_UNAVAILABLE | Spot cancel | We could not get a usable answer from the exchange. Whether the cancel landed is genuinely unknown. Retryable after a short back-off |
400 VALIDATION_ERROR, and the message often suggests a corrected value:{ "error": { "code": "VALIDATION_ERROR",
"message": "price must be a multiple of tickSize (0.01), try 60000.00" } }quantity must be a multiple of stepSize (...), quantity (...) is below the minimum (...), order notional (...) is below the minimum (...), BTC-USDT is not currently tradeable, and no live price available for BTC-USDT, try again shortly.401 INVALID_SIGNATURE403 INVALID_ORIGIN is a different failure that is checked earlier, and nothing on this list will fix it.Content-Type: application/json present on every request that has a body??, and identical to what you send?\n (0x0A), not \r\n, and there is no trailing newline at the end?5000?mgs_ prefix, with no whitespace?403 INVALID_ORIGINOrigin header at all? No server-side HTTP library adds one for you.http:// is not https://.https://api.x.example is not https://x.example.scheme://host.409 INSUFFICIENT_BALANCE when you can see the moneywallets.<COIN>.spot.available, not the total.locked is not spendable.pending deposits. Those are detected on-chain but not yet credited, and they are not part of available.