Trading API: rate limits and error codes
Every Trading API error carries a stable code. Find the code your program received in the tables below. The figures are the ones published on the Limits and Errors pages at jafx.com/developers/. The Trading API is live.
Limits
| What | Limit | Over the limit |
|---|---|---|
| Read requests per key | 20 per second, bursts of 40 | 429 rate_limited |
| Write requests per key | 5 per second, bursts of 10 | 429 rate_limited |
| All requests from one IP address, all keys together | 50 per second, bursts of 100 | 429 rate_limited |
| Orders per key (opens, closes, cancels) | Key setting: 30 per minute by default, up to 120 | 429 order_rate_limited |
| Orders per account, all keys together | 60 per minute | 429 order_rate_limited |
| Stop, target, price and expiry changes per key | Key setting: 60 per minute by default, up to 240 | 429 modification_rate_limited |
| Changes per account, all keys together | 240 per minute | 429 modification_rate_limited |
| Volume per order | Key setting | 422 volume_limit_exceeded |
| Open positions and pending orders | Key setting | 422 position_limit_exceeded |
| Daily loss | Key setting | 403 daily_loss_limit_reached |
| Stream connections per key | 2; a third replaces the oldest | The oldest closes with code 4409 |
| Active keys and connected AI apps per account | 10 together | Revoke a key or disconnect an app before adding another |
| Key lifetime | 1 to 365 days, 90 by default | 401 api_key_expired |
| Proposal lifetime | 10 minutes | The proposal expires |
| Failed authentications | 10 in a minute from one IP address | That address is blocked for 10 minutes |
A 429 or 503 answer comes with a Retry-After header, in seconds. Wait that long, then send the same call again.
Key and access errors
| Code | Meaning | What to do |
|---|---|---|
401 invalid_api_key |
The key is missing, malformed or unknown. | Check the Authorization: Bearer header and the key. |
401 api_key_expired |
The key is past its expiry date. | Create or roll a key on the Developers page of the web trader. |
401 api_key_revoked |
The key was revoked. | Create a new key. |
403 api_key_suspended |
JAFX has suspended the key. | Contact support. |
403 ip_not_allowed |
The request came from an address outside the key's IP lock. | Call from an allowed address, or create a key locked to the new address. A key's lock can't be changed after it is created. |
403 insufficient_scope |
The key's type does not allow this call (a Read-only key cannot trade), or MCP is off for the key. | Use a key of the right type. |
403 account_not_accessible |
The account in the address is not the key's account. | Use the account number that GET /me returns. |
403 live_trading_disabled |
Live trading through the API is switched off, or a demo key was used on a live account. | Use a demo account, or create a key for the live account. |
403 account_read_only |
The account is read-only. | Contact support. |
Trading-state errors
| Code | Meaning | What to do |
|---|---|---|
409 sign_in_required |
The account has no active trading session: 24 hours passed since the last password login to the web trader, or API trading was stopped. Nothing was sent. | Log in to the web trader with your password, or select Renew on its Developers page, then retry. For programs that run for days, switch on Keep my bots trading around the clock. |
423 trading_halted |
JAFX has paused API trading for everyone, for the account or for the key. Closing positions may still be allowed. | Wait until GET /me shows trading on again. |
403 daily_loss_limit_reached |
Today's loss reached the key's limit. New positions are refused. | Wait for the next broker day (midnight Europe/Athens). Closing still works. |
403 symbol_not_allowed |
The instrument is not on the key's list, or is excluded from API trading. | Trade another instrument, or create a key that allows it. |
422 volume_limit_exceeded |
The order is larger than the key's Max lots per order. | Send a smaller order. |
422 position_limit_exceeded |
The order would exceed the key's Max open positions. | Close or cancel something first. |
Order errors
| Code | Meaning | What to do |
|---|---|---|
422 invalid_volume |
The volume is not a multiple of the instrument's step, or is outside its minimum and maximum. | Check the instrument with GET /symbols/{symbol}. |
422 invalid_stops |
A stop loss or take profit is on the wrong side of the price or too close to it. | Move it further away. |
422 rejected_by_broker, 422 rejected |
The order was refused. detail or failure says why. |
Do not resend it unchanged. |
409 order_busy |
The position or order is being processed. | Wait for Retry-After, then retry. |
404 order_not_found |
No open position or pending order with that ticket on this account. | Read the positions and orders again. |
428 idempotency_key_required |
An order request was sent without an Idempotency-Key header. |
Add one. |
409 idempotency_conflict |
The same Idempotency-Key was already used for a different request. |
Use a new one for a new order. |
503 broker_unavailable, 503 broker_busy, 503 service_unavailable |
The trading connection or the API is briefly unavailable. | Wait for Retry-After, then retry the same call with the same Idempotency-Key. |
500 internal_error |
Something unexpected went wrong. | Retry later. If it continues, contact support with the request_id. |
Answers that are not errors
202with"status": "pending": the order is still being decided. Follow it on the orders stream or poll the request. Do not send it again.202with"status": "outcome_unknown": the connection failed while the order was in flight, so it may or may not have executed. Poll the request until it resolves. Never resend it under a newIdempotency-Key.202with"status": "awaiting_confirmation": a proposal was created and nothing was sent. Confirm it on the Developers page of the web trader, under Proposals waiting for you.
Retrying safely
- Send every order with its own
Idempotency-Key(a UUID is ideal) and reuse it for every retry of that order. A retry then returns the original answer and never trades twice. The key stays bound to its answer for 72 hours. - A stream that closes with code 4401 has a missing, invalid, expired, revoked or suspended key: fix the key before reconnecting. Code 4409 means a newer connection with the same key replaced it: check whether another copy of your program is running.
Need help?
Quote the request_id from the error, or the X-Request-Id header of the response. Never send us your API key or your password.
We are available 24/7 via live chat or email (support@jafx.com).
Was this article helpful?
Thank you for telling us.