Skip to main content
Developers

Errors

Errors are problem documents with a stable code. Branch on the code; the title and detail are for people and may be reworded.

Format

JSON
{
  "type": "https://terminal.jafx.com/trading-api/problems/invalid_request",
  "title": "Invalid request",
  "status": 422,
  "code": "invalid_request",
  "detail": "volume: must be positive",
  "request_id": "req_01JQ8ZK1V6T3N8R2XM5QW7HB4C",
  "details": [{ "field": "volume", "message": "must be positive" }]
}

Responses use Content-Type: application/problem+json. details is present when there is more to say, for example the fields that failed validation, or the level of a trading halt. A Retry-After header (seconds) comes with every error that is worth retrying.

Keys and access

CodeHTTPMeaningWhat to do
invalid_api_key401The key is missing, malformed or unknown.Check the Authorization header and the key.
api_key_expired401The key is past its expires_at.Create or roll a key.
api_key_revoked401The key was revoked.Create a new key.
api_key_suspended403JAFX has suspended the key.Contact support.
invalid_token401MCP only: an app's sign-in token (from Connect with just the address) is malformed or unknown, has expired, or its app was disconnected. The answer's WWW-Authenticate header says where to sign in.Refresh the token, or sign in again. A suspended app gets api_key_suspended.
ip_not_allowed403The request came from an address outside the key's IP lock (ip_allowlist).Call from an allowed address, or create a key locked to the new address. A key's IP lock can't be changed after it is created.
insufficient_scope403The key lacks the scope this call needs (details.required), or MCP is off for the key.Use a key with the right scope.
account_not_accessible403The account in the URL is not the key's account.Use the account from GET /me.
live_trading_disabled403Live trading through the API is switched off, or this key was created for a demo account and the account is live.Use a demo account, or create a key for the live account.
account_read_only403The broker has made the account read-only.Contact support.

Limits and trading state

CodeHTTPMeaningWhat to do
symbol_not_allowed403The instrument is not on the key's allow-list, or is excluded from API trading.Trade another instrument, or change the key.
volume_limit_exceeded422The volume is above the key's max_volume_per_order.Send a smaller order.
position_limit_exceeded422The order would exceed max_open_positions (positions plus pending orders).Close or cancel something first.
daily_loss_limit_reached403Today's loss reached the key's limit; new positions are refused. details has the figures.Wait for the next broker day (midnight Europe/Athens). Closing still works.
sign_in_required409Your account has no active trading session: 24 hours passed since its last sign-in to JAFX Terminal, or it was stopped. With around-the-clock trading on, JAFX signs in again by itself, so you see this only when the trading account refused the saved password (GET /me → session.ended_reason: password_refused). Nothing was sent.Sign in to JAFX Terminal, or press Renew on its Developers page, then retry with the same Idempotency-Key. After password_refused, switch around-the-clock trading on again with the current password.
trading_halted423JAFX has paused API trading. details.level is global, account or key; details.mode is off or close_only.Wait until GET /me shows trading on.
rate_limited429Too many requests per second for this key, or from your IP address across all keys (see Limits).Wait for Retry-After.
order_rate_limited429Too many orders per minute, for the key or for the account.Wait for Retry-After.
modification_rate_limited429Too many stop, target or price changes per minute.Wait for Retry-After, and change stops less often.

Requests

CodeHTTPMeaningWhat to do
invalid_request422 (400 for a body that is not JSON, 413 above 64 KB)A parameter or field is missing or invalid; details lists them.Fix the request.
idempotency_key_required428A write was sent without an Idempotency-Key header.Add one.
idempotency_conflict409The key was already used for a different request.Use a new key for a new order.
request_in_progress409The first request with this key is still running.Wait for Retry-After, then retry with the same key.
request_already_failed409The broker already refused this request.Send a corrected request with a new key.
order_not_found404No open position (or pending order) with that ticket on this account.Re-read positions or orders.
request_not_found404No order request with that request_id for this account.Check the ID.
symbol_not_available404Unknown instrument.See GET /symbols.
not_found404No such endpoint.Check the path.
feature_disabled404 or 503The feature is not enabled on this server.—

Broker and service answers

CodeHTTPMeaningWhat to do
invalid_volume422The volume is not a multiple of the instrument's step, or is outside its minimum and maximum.Check GET /symbols/{symbol}.
invalid_stops422A stop loss or take profit is on the wrong side of the price or too close to it.Move it further away.
rejected_by_broker422The broker's routing refused the request.See detail; do not retry unchanged.
rejected422The broker decided against the order (failure says why).See failure.
order_busy409The position or order is being processed, for example covered at a liquidity provider, so the broker refused the request.Wait for Retry-After, then send it again with a new Idempotency-Key: the old one keeps this refusal.
broker_throttled429The broker asked JAFX to slow down. Nothing was kept of the request.Wait for Retry-After, then retry with the same key.
broker_unavailable503The connection to the broker is down or reconnecting, or account data and trading are not available yet for your account's server (GET /status shows each server under broker.servers). Nothing was sent.Wait for Retry-After, then retry with the same key.
broker_busy503Too many requests are waiting for the broker. Nothing was sent.Wait for Retry-After, then retry with the same key.
service_unavailable503The Trading API itself is restarting (for example for an update, usually a few seconds), cannot be reached, or did not answer in time. After a timeout, a write may have gone through.Wait for Retry-After, then retry the same call. Retry a write with the same Idempotency-Key: if the first call got through, you get its original answer.
internal_error500Something unexpected went wrong.Retry later. If it persists, contact support with the request_id.

Over MCP: the next line

An MCP tool that refuses returns the same problem document as the tool's error, with one more field, next: a sentence in plain words for the AI model, saying what to do next and whether that is the account owner's to do, such as signing in again, when the daily loss stop resets, how long to wait, or which tool to call. The MCP endpoint's own refusals (a wrong key, MCP off for the key, too many requests) carry it too. REST answers are unchanged and have no next.

JSON
{
  "type": "https://terminal.jafx.com/trading-api/problems/daily_loss_limit_reached",
  "title": "Daily loss limit reached",
  "status": 403,
  "code": "daily_loss_limit_reached",
  "detail": "The daily loss limit for this key is reached; new positions are refused until the next broker day",
  "details": { "day": "2026-11-13", "loss": "104.20", "limit": "100.00" },
  "next": "Today's loss reached this key's daily loss stop: new positions are refused until the broker's next day starts at 2026-11-13T22:00:00.000Z (midnight in Athens). Closing positions, cancelling orders and changing stops still work. Tell the client."
}

Programs should keep branching on code: next may be reworded.

Four codes come only from MCP tools, which have no REST route:

CodeHTTPMeaningWhat to do
help_centre_unavailable503search_help or read_help_article: JAFX's help centre didn't answer within a few seconds, or is busy.Try once more after a short wait, or open jafx.com/help.
help_article_not_found404read_help_article: the help centre has no article with that id.Use an id search_help gave.
feature_request_limit429request_feature: the account sent 5 feature requests in the last 24 hours, the most allowed.Send it after Retry-After; list_feature_requests shows the ones sent.
tool_not_found404The MCP server has no tool by the name called.Use a tool tools/list gives; for something none of them does, request_feature.

An MCP call whose inputs don't fit the tool (a value it doesn't take, such as an order type other than market, limit or stop) answers 422 invalid_request with the reason in detail, and its next line says to fix the inputs or, for something JAFX doesn't offer, to send a feature request.

Stream errors

On the WebSocket stream, problems arrive as {"op": "error", "code": …, "message": …} frames using the same codes, plus connection_replaced just before a 4409 close. See Streaming for the close codes.

Automated and AI-driven trading can lose money quickly; nothing in these docs is investment advice.

JAFX (PTY) LTD · FSCA FSP No. 52058 · Trading leveraged derivatives with JAFX carries a high risk of losing money rapidly. It is not suitable for everyone.