All error responses follow a unified format:
`{
"error": `{
"name": "<ERROR_CODE>",
"message": "<error description>"
}`
}`
The following errors are shared across all authenticated endpoints.
| Error Scenario | HTTP Status | error.name | error.message |
|---|
Missing api-key header | 401 | API_HEADER_MISSING | missing header api-key |
Missing signature header | 401 | API_HEADER_MISSING | missing header signature |
Missing site-enum header | 400 | API_HEADER_MISSING | missing header site-enum |
Missing tonce header | 401 | API_HEADER_MISSING | missing header tonce |
| Tonce timestamp expired or invalid | 401 | API_REQUEST_EXPIRED | API request expired |
| HMAC signature verification failed | 401 | INVALID_API_SIGNATURE | invalid API signature |
| API Key lacks order placement permission (PLACE_ORDER role) | 403 | ACCESS_DENIED | access denied |
| Endpoint not found (unregistered route) | 404 | NOT_FOUND | Not found |
| auth-service returned 401 | 401 | AUTH_SERVICE_UNABLE_TO_AUTH | unable to auth with auth service |
| auth-service returned 403 | 403 | AUTH_SERVICE_ACCESS_DENIED | auth service access denied |
| auth-service returned 404 | 400 | AUTH_SERVICE_NOT_FOUND | auth service not found |
| auth-service returned other errors | 500 | AUTH_SERVICE_INTERNAL_SERVER_ERROR | auth service internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Trading endpoints rate exceeded (POST/DELETE /order) | 429 | EXCEEDED_RATE_LIMIT | rate limit exceeded |
| Query endpoints rate exceeded (GET /order, /execution, /user/wallet) | 429 | EXCEEDED_RATE_LIMIT | rate limit exceeded |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Uncaught non-HttpException error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message | |
|---|
| Missing user info (no apiKey or unable to resolve userId) | 400 | REQUEST_MISSING_USER_INFO | request is missing information needed to identify the user | Business Logic |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing symbol parameter | 400 | INVALID_SYMBOL | invalid symbol |
| Missing side parameter | 400 | INVALID_SIDE | invalid order side |
| Missing ordType parameter | 400 | INVALID_TYPE | invalid order type |
| Missing orderQty parameter | 400 | REQUIRED_QTY | order quantity is required |
| Missing price for Limit order | 400 | REQUIRED_PRICE | order price is required |
| Incompatible ordType and timeInForce | 400 | INVALID_ORDER_TYPE_AND_TIME_IN_FORCE | order type {ordType} and time in force {timeInForce} don't work together |
| Incompatible ordType and execInst | 400 | INVALID_ORDER_TYPE_AND_EXEC_INST | order type {ordType} and exec inst {execInst} don't work together |
| Invalid currency pair (MG engine) | 400 | INVALID_CURRENCY | order invalid currency |
| Invalid price (MG engine) | 400 | INVALID_PRICE | order invalid price |
| Invalid price step | 400 | INVALID_PRICE_STEP | order invalid price step |
| Invalid quantity | 400 | INVALID_QTY | order invalid quantity |
| Invalid quantity step | 400 | INVALID_QTY_STEP | order invalid quantity step |
| Insufficient balance (cash) | 400 | INSUFFICIENT_HOLDINGS | order insufficient holdings |
| Insufficient balance (holdings) | 400 | INSUFFICIENT_HOLDINGS | order insufficient holdings |
| No holdings | 400 | NO_HOLDINGS | order no holdings |
| No liquidity (IOC order) | 400 | NO_LIQUIDITY | order no liquidity |
| Negative price | 400 | PRICE_NEGATIVE | order price negative |
| Price too high | 400 | PRICE_TOO_HIGH | order price too high |
| Price too low | 400 | PRICE_TOO_LOW | order price too low |
| Zero price | 400 | PRICE_ZERO | order price zero |
| Quantity too large | 400 | QTY_TOO_LARGE | order quantity too large |
| Quantity too small | 400 | QTY_TOO_SMALL | order quantity too small |
| Order value too large | 400 | VALUE_TOO_LARGE | order value too large |
| Order value too small | 400 | VALUE_TOO_SMALL | order value too small |
| Post-Only order would match immediately | 400 | POST_ONLY_MATCH | post only order would match |
| Account suspended | 400 | ACCOUNT_SUSPENDED | order account suspended |
| User suspended | 400 | USER_SUSPENDED | order user suspended |
| Active orders limit exceeded | 400 | ACTIVE_ORDERS_LIMIT_EXCEEDED | active orders limit exceeded |
| Duplicate clientOrderId | 400 | DUPLICATE_CLIENT_ORDER_ID | duplicate client order id |
| Concentration limit restriction | 400 | CONCENTRATION_LIMIT_RESTRICTED | order rejected due to concentration limit restriction |
| Trading closed for instrument | 400 | TRADING_NOT_AVAILABLE | trading is closed for this instrument |
| Invalid settlement currency | 400 | INVALID_SETTLEMENT_CURRENCY | order invalid settlement currency |
| gRPC place order business error (code != 0) | 400 | GRPC_ORDER_ERROR | {resp.message} |
| gRPC timeout (DEADLINE_EXCEEDED) | 408 | API_TIMEOUT | A service timed-out. |
| gRPC service unavailable (UNAVAILABLE) | 500 | SERVICE_TEMPORARILY_UNAVAILABLE | service is temporarily not available |
| Matching engine unavailable (SharedMemoryTableFull, etc.) | 400 | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| MG API timeout (ECONNABORTED) | 408 | API_TIMEOUT | A service timed-out. |
| MG API internal error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Order not found | 400 | ORDER_NOT_FOUND | order not found |
| Invalid symbol parameter | 400 | INVALID_SYMBOL | invalid symbol |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing orderId or clientOrderId | 400 | REQUIRED_AT_LEAST_ONE_OF_ORDER_ID_OR_CLIENT_ORDER_ID | required at least one of order id or client order id |
| Invalid orderId | 400 | INVALID_ORDER_ID | invalid order id |
| Order already cancelled | 400 | ALREADY_CANCELLED | order already cancelled |
| Order already fully matched | 400 | ALREADY_MATCHED | order already matched |
| Order already amended | 400 | ALREADY_AMENDED | order already amended |
| Order not found | 400 | ORDER_NOT_FOUND | order not found |
| gRPC cancel order business error (code != 0) | 400 | GRPC_ORDER_ERROR | {resp.message} |
| gRPC timeout | 408 | API_TIMEOUT | A service timed-out. |
| gRPC service unavailable | 500 | SERVICE_TEMPORARILY_UNAVAILABLE | service is temporarily not available |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| gRPC cancel all business error (code != 0) | 400 | GRPC_ORDER_ERROR | {resp.message} |
| gRPC timeout | 408 | API_TIMEOUT | A service timed-out. |
| gRPC service unavailable | 500 | SERVICE_TEMPORARILY_UNAVAILABLE | service is temporarily not available |
| MG engine unavailable | 400 | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Invalid symbol parameter | 400 | INVALID_SYMBOL | invalid symbol |
| acctGroupUuid exceeds max length | 400 | BAD_REQUEST | parameter acctGroupUuid exceeds max length |
| Upstream spot-rest 4xx error | 400 | BAD_REQUEST | {upstream message} |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing orderId or clientOrderId | 400 | REQUIRED_ONE_OF_ORDER_ID_OR_CLIENT_ORDER_ID | required exclusively one of order id or client order id |
| Invalid orderId | 400 | INVALID_ORDER_ID | invalid order id |
| Invalid clientOrderId | 400 | INVALID_CLIENT_ORDER_ID | invalid client order id |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message | |
|---|
| Missing symbol parameter | 400 | INVALID_SYMBOL | invalid symbol | |
| Symbol does not exist | 400 | INVALID_SYMBOL | invalid symbol | Business Logic |
| Upstream mktdata 4xx error | 400 | BAD_REQUEST | {upstream message} | |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. | |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error | |
| Error Scenario | HTTP Status | error.name | error.message | |
|---|
| Missing symbol parameter | 400 | INVALID_SYMBOL | invalid symbol | |
| Invalid depth parameter | 400 | INVALID_ORDER_BOOK_DEPTH | invalid order book depth | |
| Symbol does not exist | 400 | INVALID_SYMBOL | invalid symbol | Business Logic |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. | |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error | |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing symbols parameter | 400 | INVALID_SYMBOL | invalid symbol |
| Invalid depth parameter | 400 | INVALID_ORDER_BOOK_DEPTH | invalid order book depth |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| acctGroupUuid exceeds max length | 400 | BAD_REQUEST | parameter acctGroupUuid exceeds max length |
| Currency not found or empty wallet | 400 | CURRENCY_NOT_FOUND | currency not found or empty wallet for that currency |
| MG API timeout | 408 | API_TIMEOUT | A service timed-out. |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing symbol parameter | 400 | REQUIRED_SYMBOL | symbol is required |
| Missing granularity parameter | 400 | REQUIRED_GRANULARITY | granularity is required |
| Invalid granularity value | 400 | INVALID_GRANULARITY | invalid granularity |
| Invalid limit parameter | 400 | INVALID_LIMIT | invalid limit |
| Symbol does not exist | 400 | INVALID_SYMBOL | invalid symbol |
| Kline service timeout | 408 | API_TIMEOUT | A service timed-out. |
| Kline service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Invalid report period parameter | 400 | BAD_REQUEST | {validation message} |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing x-user-uuid header | 400 | BAD_REQUEST | Missing required header: x-user-uuid |
| Invalid report period parameter | 400 | BAD_REQUEST | {validation message} |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing x-user-uuid header | 400 | BAD_REQUEST | Missing required header: x-user-uuid |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Invalid report period parameter | 400 | BAD_REQUEST | {validation message} |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Missing x-user-uuid header | 400 | BAD_REQUEST | Missing required header: x-user-uuid |
| Invalid report period parameter | 400 | BAD_REQUEST | {validation message} |
| Downstream service error | 500 | INTERNAL_SERVER_ERROR | internal server error |
| Error Scenario | HTTP Status | error.name | error.message |
|---|
| Dependent service unhealthy | 503 | (no error object, returns service health status list) | — |
This endpoint has no error scenarios and always returns 200.
The following error codes originate from the legacy matching engine.
| Legacy Engine Error Message | Mapped error.name | Mapped error.message |
|---|
| OrderAccountSuspended | ACCOUNT_SUSPENDED | order account suspended |
| OrderImmediateNoMatch | NO_LIQUIDITY | order no liquidity |
| OrderInsufficientCash | INSUFFICIENT_HOLDINGS | order insufficient holdings |
| OrderInsufficientHoldings | INSUFFICIENT_HOLDINGS | order insufficient holdings |
| OrderInvalidCurrency | INVALID_CURRENCY | order invalid currency |
| OrderInvalidExpiryDate | INVALID_EXPIRY_DATE | order invalid expiry date |
| OrderInvalidExpiryTime | INVALID_EXPIRY_TIME | order invalid expiry time |
| OrderInvalidPrice | INVALID_PRICE | order invalid price |
| OrderInvalidPriceStep | INVALID_PRICE_STEP | order invalid price step |
| OrderInvalidQuantity | INVALID_QTY | order invalid quantity |
| OrderInvalidQuantityStep | INVALID_QTY_STEP | order invalid quantity step |
| OrderInvalidSettlementCurrency | INVALID_SETTLEMENT_CURRENCY | order invalid settlement currency |
| OrderInvalidSide | INVALID_SIDE | order invalid side |
| OrderInvalidType | INVALID_TYPE | order invalid type |
| OrderNoHoldings | NO_HOLDINGS | order no holdings |
| OrderPriceNegative | PRICE_NEGATIVE | order price negative |
| OrderPriceTooHigh | PRICE_TOO_HIGH | order price too high |
| OrderPriceTooLow | PRICE_TOO_LOW | order price too low |
| OrderPriceZero | PRICE_ZERO | order price zero |
| OrderQuantityTooLarge | QTY_TOO_LARGE | order quantity too large |
| OrderQuantityTooSmall | QTY_TOO_SMALL | order quantity too small |
| OrderStatusSetNoCancelCancelled | ALREADY_CANCELLED | order already cancelled |
| OrderStatusSetNoCancelMatched | ALREADY_MATCHED | order already matched |
| OrderStatusSetNoCancelAmended | ALREADY_AMENDED | order already amended |
| OrderUserSuspended | USER_SUSPENDED | order user suspended |
| OrderValueTooLarge | VALUE_TOO_LARGE | order value too large |
| OrderValueTooSmall | VALUE_TOO_SMALL | order value too small |
| OrderPostOnlyMatch | POST_ONLY_MATCH | post only order would match |
| OrderAmendNotavailable | AMEND_NOT_AVAILABLE | order amend not available |
| OrderInstrumentmarketClosed | TRADING_NOT_AVAILABLE | trading is closed for this instrument |
| InvalidOrder | ALREADY_CANCELLED | order already cancelled |
| CONCENTRATION_LIMIT_RESTRICTED | CONCENTRATION_LIMIT_RESTRICTED | order rejected due to concentration limit restriction |
| SessionError | SESSION_ERROR | session error |
| SharedMemoryTableFull | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| SystemAlreadyUnloading | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| SystemClosed | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| SystemNotReady | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| SystemSuspended | ENGINE_UNAVAILABLE | engine is temporarily unavailable - try later |
| UnauthorisedRequest | UNAUTHORISED_REQUEST | unauthorised request |
| UnauthorisedTransaction | UNAUTHORISED_TRANSACTION | unauthorised transaction |
| Unauthorized | AUTH_SERVICE_UNABLE_TO_AUTH | unable to auth with auth service |
| Forbidden | ACCESS_DENIED | access denied |
| Not Found | NOT_FOUND | not found |
| Method Not Allowed | METHOD_NOT_ALLOWED | method not allowed |
| DUPLICATE_CLIENT_ORDER_ID | DUPLICATE_CLIENT_ORDER_ID | duplicate client order id |
| INTERNAL_SERVER_ERROR | INTERNAL_SERVER_ERROR | internal server error |
| INVALID_ACCOUNT | INVALID_ACCOUNT_CODE | invalid account code |
| INVALID_EXTERNAL_ACCOUNT | INVALID_EXTERNAL_ACCOUNT | invalid external account |
| INVALID_INSTRUMENT | INVALID_CURRENCY | invalid currency |
| INVALID_INSTRUMENT_MARKET | INVALID_SYMBOL | invalid symbol |
| INVALID_ORDER_ID | INVALID_ORDER_ID | invalid order id |
| INVALID_ORDER_QTY | INVALID_QTY | invalid order quantity |
| INVALID_ORDER_TYPE | INVALID_TYPE | invalid order type |
| INVALID_PRICE | INVALID_PRICE | invalid order price |
| INVALID_SIDE | INVALID_SIDE | invalid order side |
| INVALID_TIME_IN_FORCE | INVALID_TIME_IN_FORCE | invalid order time in force |
| INVALID_EXEC_INST | INVALID_EXEC_INST | invalid order execution instruction |
| REQUIRED_ACCOUNT_CODE | REQUIRED_ACCOUNT_CODE | account code is required |
| REQUIRED_INSTRUMENT_MARKET | REQUIRED_SYMBOL | symbol is required |
| REQUIRED_PRICE | REQUIRED_PRICE | order price is required |
| REQUIRED_ORDER_ID | REQUIRED_ORDER_ID | order id is required |
| REQUIRED_ORDER_QTY | REQUIRED_QTY | order quantity is required |
| ORDER_NOT_FOUND | ORDER_NOT_FOUND | order not found |
| ACTIVE_ORDERS_LIMIT_EXCEEDED | ACTIVE_ORDERS_LIMIT_EXCEEDED | active orders limit exceeded |
| UNEXPECTED_ERROR | UNEXPECTED_ERROR | unexpected error |
| MAJOR_VERSION_MISMATCH | MAJOR_VERSION_MISMATCH | major version mismatch |
| VERSION_CANNOT_PARSE | VERSION_CANNOT_PARSE | version cannot parse |
| HTTP Status | Meaning | Typical Scenarios |
|---|
| 400 | Bad Request | Parameter validation failure, business logic errors, downstream business code non-zero |
| 401 | Unauthorized | Authentication failure (missing headers, invalid signature, expired tonce) |
| 403 | Forbidden | Insufficient permissions (API Key lacks order permission, auth-service denied) |
| 404 | Not Found | Unregistered route |
| 408 | Request Timeout | MG API timeout, gRPC DEADLINE_EXCEEDED |
| 410 | Gone | Deprecated endpoints (CoinGecko/CoinMarketCap) |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Internal system error, downstream service unavailable |
| 503 | Service Unavailable | Health check failed (dependent service unhealthy) |