Troubleshooting
Public API errors have two layers:
-
HTTP status code
Shows the transport-level result of the request.
-
API error code
Shows the business or platform reason of the error.
REST error response:
{
"code": 10014,
"error_message": "InvalidVolume"
}
WebSocket error response:
{
"id": "request-1",
"code": 400,
"error_message": "Invalid subscription request"
}
For asynchronous trading operations, the REST request may return 202 Accepted, but the final result can still be rejected later in transaction_event or in operation status.
Example:
{
"event_type": "transaction_event",
"operation_id": "789",
"status": "rejected",
"error_code": 10014,
"error_message": "Invalid subscription request",
"payload": {}
}
HTTP status guide
| HTTP status | Meaning | Typical client action |
|---|---|---|
| 400 | Invalid request or business validation failed | Fix request parameters |
| 401 | Authorization failed | Signed requests use the public error model: json { "code": 1001, "error_message": "AUTH_INVALID_SIGNATURE" } |
| 403 | Permission denied | Check API key permissions |
| 404 | Resource or operation not found | Check identifier or retention period |
| 410 | Invalid account | Check account ID and access |
| 429 | Rate limit exceeded | Slow down requests and retry later |
| 500 | Internal server error | Retry with backoff or report issue |
Trading Error Codes
These codes are based on the existing trading result code model and old error mapping. It will be updated in the next versions. Some codes may be exposed directly, while others may be mapped to public API error names.
| Code | Name | Meaning / likely reason | Client action |
|---|---|---|---|
| 0 | Unknown | Unknown or non-classified error | Retry only if safe; report if repeated |
| 1000 | InvalidAPIKey | API key is unknown, expired, or does not match the signed payload. | Check EXN-API-KEY and api_key inside EXN-DATA . |
| 1001 | InvalidSignature | Signature validation failed. | Check EXN-DATA , EXN-SIGN , private key, payload serialization, and base64url encoding. |
| 1002 | PermissionDenide | API key is valid but not allowed to access the requested account, IP, or operation scope. | Check account access, source IP restrictions, and API key permissions. |
| 10004 | Requote | Requested price is no longer valid for instant execution | Refresh price and retry with new price or deviation |
| 10006 | Reject | Trade request rejected | Check request, account state, instrument state |
| 10007 | Cancel | Operation cancelled | Check operation status and retry only if needed |
| 10013 | Invalid | Malformed or invalid request parameters | Fix request payload or query parameters |
| 10014 | InvalidVolume | Volume is too small, too big, or not aligned to step | Check volume_min, volume_max, volume_step |
| 10015 | InvalidPrice | Invalid price value | Check price format, precision, and market side |
| 10016 | InvalidStops | Invalid SL/TP or stop level validation failed | Check stop level rules and SL/TP distance |
| 10017 | TradeDisabled | Trading is disabled for account or instrument | Check account and instrument status |
| 10018 | MarketClosed | Trading session is closed | Check instrument trading sessions |
| 10019 | NoMoney | Not enough margin / equity | Reduce volume or close exposure |
| 10021 | PriceOff | No valid quote / price is unavailable | Wait for tick update and retry |
| 10024 | TooManyTradeRequests | Too many trading requests | Apply client-side throttling |
| 10031 | Connection | Downstream connection problem | Retry with backoff |
| 10033 | ReachedPendingOrdersLimit | Too many pending orders | Cancel old orders or reduce new order creation |
| 10044 | CloseOnly | Account or instrument is in close-only mode | Only close positions or cancel orders |
Error Handling Guide
1. Validate request before sending
Before sending trading requests:
-
Get instrument conditions.
-
Validate volume against
volume_min,volume_max,volume_step. -
Validate price precision against
point_digits. -
Check account status and instrument trading mode.
-
Use
Idempotency-Keyfor all mutating trading requests.
2. Handle asynchronous flow correctly
For trading methods:
-
Send REST request.
-
Receive
ACKwithoperation_id. -
Wait for
transaction_event. -
Match by
operation_idorclient_request_id. -
If event is not received, poll operation status.
REST request -> ACK accepted -> transaction_event success / rejected / failed
3. Retry only safe cases
Safe to retry with the same Idempotency-Key:
-
network timeout before ACK
-
connection interruption
-
unknown client-side delivery state
Use a new Idempotency-Key only for a new logical request.
4. Do not blindly retry validation errors
Do not retry without changing request data for:
-
Invalid -
InvalidVolume -
InvalidPrice -
InvalidStops -
TradeDisabled -
MarketClosed -
CloseOnly
5. Use backoff for platform or rate errors
Use exponential backoff for:
-
Timeout -
Connection -
TooManyTradeRequests -
ResultTooManyRequests -
500 Internal Server Error
6. Reconcile state after reconnect
WebSocket streams do not provide durable replay.
After reconnect:
-
resubscribe
-
receive a new
trading_state_snapshot -
reconcile open orders, open positions, and account state
-
use operation status for recently accepted operations
7. Common causes of signed request failures
-
EXN-API-KEY does not match api_key inside EXN-DATA.
-
EXN-IDEMPOTENCY-KEY does not match idempotency_key inside EXN-DATA.
-
Signed GET request does not send an empty EXN-IDEMPOTENCY-KEY.
-
EXN-TIMESTAMP does not match timestamp inside EXN-DATA.
-
EXN-SIGN-VERSION does not match sign_version inside EXN-DATA.
-
The client signs the base64url EXN-DATA string instead of decoded payload bytes.
-
Request path or query string was changed after signing.
-
Query parameters were reordered or re-encoded after signing.
-
Body hash was calculated from a different JSON representation than the body actually sent.
-
Base64url encoding includes = padding.
Common Troubleshooting Scenarios
Order was accepted but no result event received
Recommended action:
-
Check WebSocket connection.
-
Poll operation status:
GET /v1/trading/accounts/{account_id}/operations/{operation_id} -
Reconnect and resubscribe.
-
Reconcile with trading snapshot.
Requote received
Meaning:
- The requested price differs from current execution price more than allowed by deviation.
Action:
-
Get latest tick.
-
Retry with updated price.
-
For instant execution, optionally provide deviation.
-
For market execution, deviation is ignored.
Invalid volume
Meaning:
- Volume violates instrument rules.
Action:
-
Call instrument conditions.
-
Check
volume_min,volume_max,volume_step. -
Adjust volume before retrying.
Invalid stops
Meaning:
- SL/TP or pending order price violates stop-level or price-distance rules.
Action:
-
Move SL/TP farther from market price.
-
Check instrument precision.
-
Retry with corrected values.
Market closed
Meaning:
- Instrument trading session is closed.
Action:
-
Check instrument trade sessions.
-
Retry when market is open.
Too many requests
Meaning:
- Client exceeded request limits.
Action:
-
Call rate limits endpoint.
-
Track usage locally.
-
Reduce request frequency.
-
Prefer WebSocket streams over polling.
HMR subscription issues
HMR is delivered through the main Server Events stream.
Use:
/v1/server-events/accounts/{account_id}/ws/events
Common issues:
| Problem | Likely cause | Client action |
| --- | --- | --- |
| HMR subscription is rejected | One or more requested instruments are not available for the account. | Use GET /v1/configuration/accounts/{account_id}/instruments and subscribe only to available instruments. |
| Client receives no HMR events | No active or scheduled HMR periods for subscribed instruments. | Keep subscription active or check snapshot after subscription. |
| Client state differs from server state | Missed update or reconnect happened. | Resubscribe and replace local state with the latest hmr_snapshot. |
| HMR period disappeared | Period was removed by removed_period_ids. | Remove matching period_id from local HMR state. |
| HMR period changed | Period was included in upserted_periods. | Replace local period with the same period_id. |
---
## Notes for Current Implementation
Current handlers return asynchronous ACK responses with `operation_id` and optional `client_request_id` for mutating trading methods.
Configuration handlers currently build standard JSON error responses with `code` and `message`, and use HTTP status to separate bad request, invalid account, and internal server errors.
---