Troubleshooting Your API Requests
When working with the Exness API, errors generally happen on two levels:
-
HTTP status code: This tells you if your request successfully communicated with our servers.
-
API error code: This gives you the specific business, platform, or account reason why an action couldn't be completed.Shows the business or platform reason of the error.
For background trading operations, your initial request might be accepted by our servers, but the final trade could still be rejected moments later during processing. Always check the final status of your operation.
REST error response:
{
"code": 3001,
"error_message": "REQUEST_INVALID_PARAMETERS"
}
WebSocket error response:
{
"id": "request-1",
"code": 3000,
"error_message": "REQUEST_INVALID"
}
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": 5006,
"error_message": "TRADING_RULE_INSUFFICIENT_MARGIN",
"event_time": "2026-12-14T11:46:30+00:00",
"payload": {}
}
HTTP Status Guide
Use this quick reference to understand basic connection errors and how to fix them.
| HTTP status | What It Means | How to Fix It |
|---|---|---|
| 400 | Invalid request or the details failed our validation checks. | Fix the path, method, query, or JSON body, then retry. |
| 401 | Authentication failed | Rebuild auth headers and signature for the exact request. |
| 403 | Permission denied. | Check account access, API key permissions, and operation scope. |
| 404 | Entity not found | Verify the ID and confirm the API key can access the resource. |
| 409 | State conflict or market/execution conflict | Refresh state or prices, then retry only if the action is still valid. |
| 422 | Business validation failed | Fix the business input, such as volume, margin, or price levels. |
| 429 | Rate limit exceeded. | Apply the returned limits, wait for capacity, then retry. |
| 503 | Temporary unavailability | Retry with backoff; reconnect WebSocket clients if needed. |
| 500 | Internal server error on our end. | Retry later with backoff; contact Support if it repeats. |
Trading Error Codes
If your request reaches us but cannot be processed, you will receive a specific API error code.
| Code | Name | HTTP status | Meaning / likely reason | Client action |
|---|---|---|---|---|
| 1 | SYSTEM_RATE_LIMIT | 429 | Too many requests for platform. | Slow down request rate. Retry only when safe, using backoff and idempotency for repeated trading requests. |
| 2 | SYSTEM_TEMPORARY_UNAVAILABLE | 503 | Temporary dependency issue from any service (auth,access point). | Retry with exponential backoff. Keep the same idempotency key only when retrying the same mutating request. |
| 3 | SYSTEM_INTERNAL_ERROR | 500 | Unexpected internal error from any service (auth, access point). | Retry with backoff. Contact Support if the error is repeated or blocks normal operation. |
| 1000 | AUTH_INVALID_API_KEY | 401 | Invalid token, audience. | Check EXN-API-KEY, the api_key value inside EXN-DATA, account access, and whether the key is still active. |
| 1001 | AUTH_INVALID_SIGNATURE | 401 | Invalid signature, certificate. | Rebuild the signature payload. Check method, signed path, body hash, timestamp, key format, and base64url encoding. |
| 1002 | AUTH_PERMISSION_DENIED | 403 | Valid credentials, but operation is not allowed. | Check that the API key is allowed to access the account, source IP, and operation scope. |
| 1003 | AUTH_RATE_LIMIT | 429 | Too many authentication requests. | Stop immediate retries. Wait for retry_after when provided; otherwise retry with backoff. |
| 2000 | ACCOUNT_NOT_FOUND | 404 | Account not found or unavailable from any service (auth, access point, platform). | Check account_id and make sure the API key is allowed to access this account. |
| 2001 | ACCOUNT_DISABLED | 403 | Account is disabled. | Do not send new trading requests. Check the account status or contact Support. |
| 2002 | ACCOUNT_CLOSE_ONLY | 403 | Account is close-only. | Do not open new exposure. Only close positions or cancel orders where allowed. |
| 3000 | REQUEST_INVALID | 400 | Invalid request. | Fix the request shape, path, method, body, or subscription payload before retrying. |
| 3001 | REQUEST_INVALID_PARAMETERS | 400 | Invalid request parameters. | Fix query or path parameters. Make sure signed path and transmitted path are identical. |
| 3002 | REQUEST_INVALID_PRICE | 400 | Invalid price. | Check price format, precision, instrument conditions, and whether the price is valid for the requested side. |
| 3003 | REQUEST_INVALID_TIMEFRAME | 400 | Invalid timeframe. | Use a supported timeframe for the requested market data endpoint. |
| 3004 | REQUEST_INVALID_TIME_RANGE | 400 | Invalid time range. | Fix from/to values. Keep the requested range within the allowed history window. |
| 3005 | REQUEST_INVALID_COUNT | 400 | Invalid count. | Use a valid count value for the request. |
| 3006 | REQUEST_INVALID_LIMIT | 400 | Invalid limit. | Use a valid limit value and stay within the allowed request size. |
| 3007 | REQUEST_INVALID_CURSOR | 400 | Invalid cursor. | Use the cursor exactly as returned by the API. Do not parse or modify it. |
| 3008 | REQUEST_INVALID_PRICE_TYPE | 400 | Invalid price type. | Use a supported price_type value for the requested market data endpoint. |
| 3009 | REQUEST_INVALID_FILTER_COMBINATION | 400 | Invalid filter combination. | Remove incompatible filters and retry with a supported combination. |
| 3010 | REQUEST_UNSUPPORTED_MEDIA_TYPE | 400 | Unsupported request content type. | Send JSON requests with Content-Type: application/json where a body is required. |
| 3011 | REQUEST_METHOD_NOT_ALLOWED | 405 | Unsupported method. | Use the HTTP method defined for this endpoint in the API reference. |
| 3012 | REQUEST_ORDER_NOT_FOUND | 404 | Requested order was not found. | Check the order identifier. Use only order IDs returned by the API and make sure the order belongs to the requested account. |
| 3013 | REQUEST_POSITION_NOT_FOUND | 404 | Requested position was not found. | Check the position identifier. Use only position IDs returned by the API and make sure the position still exists for the requested account. |
| 3014 | REQUEST_OPERATION_NOT_FOUND | 404 | Requested operation was not found. | Check the operation identifier. Use the operation_id returned in the ACK response or related event. |
| 3015 | REQUEST_RATE_LIMIT | 429 | Endpoint rate limit exceeded. | Stop immediate retries. Use GET /v1/configuration/accounts/{account_id}/limits, track usage locally, and wait until request capacity is available. |
| 4000 | MARKET_INSTRUMENT_NOT_FOUND | 404 | Instrument not found. | Request available instruments for the account and use an instrument name from that list. |
| 4001 | MARKET_TRADE_DISABLED | 403 | Trading disabled for instrument. | Do not send trading requests for this instrument until trading is enabled. |
| 4002 | MARKET_CLOSE_ONLY | 403 | Instrument is close-only. | Only close existing exposure for this instrument. Do not open new positions or pending orders. |
| 4003 | MARKET_SESSION_CLOSED | 409 | Trading session is closed. | Wait until the instrument trading session is open before sending the trading request. |
| 4004 | MARKET_NO_QUOTES | 503 | No quotes available. | Wait for a valid quote update and retry only if the operation is still intended. |
| 5000 | TRADING_RULE_INVALID_VOLUME | 422 | Generic invalid volume. | Check the instrument volume rules and send a valid volume. |
| 5001 | TRADING_RULE_VOLUME_TOO_SMALL | 422 | Volume is too small. | Increase volume to at least the instrument minimum volume. |
| 5002 | TRADING_RULE_VOLUME_TOO_LARGE | 422 | Volume is too large. | Reduce volume to the instrument maximum volume or lower. |
| 5003 | TRADING_RULE_INVALID_VOLUME_STEP | 422 | Invalid volume step. | Align volume to the instrument volume step. |
| 5004 | TRADING_RULE_INVALID_REMAINING_VOLUME | 422 | Invalid remaining volume. | Adjust the close or partial-close volume so the remaining position volume is valid. |
| 5005 | TRADING_RULE_INVALID_PRICE_LEVELS | 422 | Order price levels are invalid | Check stop-loss, take-profit, pending order price, and minimum distance rules. |
| 5006 | TRADING_RULE_INSUFFICIENT_MARGIN | 422 | Insufficient free margin. | Reduce volume, free margin, or close exposure before retrying. |
| 5007 | TRADING_RULE_MARGIN_LEVEL_TOO_LOW | 422 | Margin level too low. | Reduce exposure or add margin before sending new trading requests. |
| 5008 | TRADING_RULE_OPERATION_RESTRICTED | 422 | Position operation is not allowed. | Check account and instrument restrictions. Send only operations allowed for the current state. |
| 5009 | TRADING_RULE_TOO_MANY_PENDING_ORDERS | 422 | Pending order limit reached. | Cancel old pending orders or reduce new pending order creation. |
| 5010 | TRADING_RULE_TOO_MANY_OPEN_POSITIONS | 422 | Open position limit reached. | Close existing positions or reduce new position creation. |
| 6000 | EXECUTION_REQUOTE | 409 | Price changed. | Refresh the current price and submit a new request only if the trade is still intended. |
| 6001 | EXECUTION_REJECTED | 409 | Order rejected. | Check request parameters, account state, instrument state, and recent transaction events before retrying. |
Best Practices for Handling Errors
1. Double-check before you send
Always verify your details before submitting a trade request.
- Ensure your volume meets the minimum, maximum, and step requirements.
- Check that your price matches the required decimal precision.
- Verify that the market is open and your account is active.
2. Know when to retry
It is safe to automatically retry your request if you experience a network timeout, a sudden disconnection, or if you aren't sure if the request went through. However, do not automatically retry if you receive validation errors (like invalid prices, invalid volumes, or closed markets) without fixing the underlying issue first.
3. Reconnecting
If you lose your connection, your previous session data won't automatically replay. When you reconnect:
- Resubscribe to your data streams.
- Download a new snapshot of your account state.
- Cross-check your open orders and positions to ensure everything is up to date.
4. Common security signature mistakes
If your requests are failing due to a signature error, check for these common issues:
- Your API keys or timestamps do not match your data.
- You changed the request path or query details after you already signed it.
- Your data encoding includes unnecessary padding.
Common scenarios & solutions
My order was accepted, but I didn't get a final result.
- Check your connection to ensure you didn't miss the update.
- Manually check the status of your operation using your account ID and operation ID.
- If needed, reconnect and pull a fresh snapshot of your account.
I received a "Requote" error.
- This means the price you requested has changed by more than your allowed settings.
- Get the latest price update and try again.
My volume or stops are invalid.
- For invalid volume, check the specific rules for that instrument and adjust your trade size accordingly.
- For invalid stops, your Stop Loss or Take Profit is likely too close to the current market price. Move them further away and retry.
I am hitting request limits.
- You have exceeded your allowed request frequency.
- Track your usage, slow down your requests, and try to use streaming connections rather than repeatedly asking the server for updates.
Margin Requirement (HMR) Updates
Higher Margin Requirement (HMR) events are delivered directly through your main events stream.
| Problem | Likely Cause | How to Fix It |
|---|---|---|
| Subscription rejected | You are requesting an instrument that isn't available for your account. | Check which instruments are available to you and only subscribe to those. |
| No HMR events received | There are no active or scheduled HMR periods right now. | Keep your subscription active and wait for updates. |
| Out-of-sync information | You missed an update or temporarily disconnected. | Resubscribe and refresh your local data with a new 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. |