pipsocketDOCS
Guides / Reference

Errors and retcodes

The API's refusals, MT5's retcodes, and what to do about each.

Two kinds of answers say something went wrong, and they mean different things:

  • A refusal is an HTTP error with { "error": "<code>", "message": "..." }. Check error, not message (its wording may change). Almost every refusal means nothing was done. Two mean the call may have reached the account's host before the answer was lost: 503 engine_unavailable (the host disconnected while the call waited) and 504 engine_timeout. After those, a trade's outcome is unknown: retry it with the same Idempotency-Key, which returns the first request if the host recorded it, and sends it if not.
  • The kill switch is the exception. Engaging it while the terminal is away answers 503 account_not_connected with kill_switch: the switch is engaged all the same (it blocks new exposure, and survives restarts), and pending orders may already have been deleted if the terminal stopped answering part way. Read the kill switch, positions and pending orders, and engage it again: engaging again retries whatever is left (it takes no Idempotency-Key).
  • MT5's answer to a trade is 200 with "state": "done", whether MT5 filled the order or rejected it. Read result.retcode: 10009 is done; 10008 is placed (a pending order); the rest are partial fills or rejections. A rejection can come from the trade server, or from the terminal refusing to send the request at all (then result.comment is the terminal's), so done doesn't prove the broker saw it.
{
  "request": "req_5f0c2a9e41d7b3a8c6e2f190",
  "state": "done",
  "result": { "retcode": 10016, "retcode_name": "TRADE_RETCODE_INVALID_STOPS", "comment": "Invalid stops", "...": "..." },
  "message": "The stop loss or take profit is invalid for this symbol or too close to the price.",
  "sent": { "...": "..." }
}

What to do

AnswerDo
200 with "state": "done"Read result.retcode. A rejection is final: nothing more happens to that request. Change it before sending it again (with a new Idempotency-Key).
202 with "state": "pending"Don't send it again. Look it up, or wait for its request event on the stream.
401Check the key: see Authentication.
403 with error code: 1010Cloudflare refused your client's User-Agent before the API saw the call (Python's urllib sends one it refuses). Set your own User-Agent, or use a client such as requests.
404Check the account id, ticket or symbol. Closing, modifying and setting stops read the position or order fresh first: one that's gone is 404.
422Fix the field message names. Nothing was sent.
423 kill_switch_engagedThe account's kill switch is engaged: lift it to open new exposure.
503, 504Retry a trade call with the same Idempotency-Key, never a new one: if the first call was recorded you get it back, and nothing is sent twice. Most are refused before anything is sent, but after engine_unavailable or engine_timeout the first call may have been sent. A trade sent without a key can't be retried safely: check positions and history first.

Error codes

Every code the API answers with. "From" says who refuses: the API, before the account's host is reached, or the engine on the host.

StatusCodeFromMeaning
401missing_api_keyAPINo API key: send it as Authorization: Bearer <key>.
401invalid_api_keyAPIThe key is not a workspace's current key (a rolled key stops working within about a minute).
404no_such_accountEngineNo such account, or one the key's workspace doesn't have: the two look the same.
404no_such_orderEngineThe account has no pending order with that ticket (read fresh from the terminal).
404no_such_positionEngineThe account has no open position with that ticket (read fresh from the terminal).
404no_such_requestEngineThe account has no request with that id (requests are kept 7 days).
404no_such_symbolEngineThe broker has no symbol by that name.
422invalid_requestEngineA field, query parameter or header is missing, malformed or not allowed, or the body is not JSON. Nothing was sent.
422range_too_largeEngineThe history range holds more than one answer can carry: ask for a shorter range.
423kill_switch_engagedEngineThe account's kill switch is engaged: new orders and changes to pending orders are refused until it is lifted. Nothing was sent.
503account_not_connectedEngineThe account's terminal is not connected to the engine (stopped, starting, or restarting). Nothing was sent, except by the kill switch: engaging it still engages it, and may already have deleted pending orders.
503bridge_outdatedEngineThe account's terminal runs an older bridge that can't trade: restart the account to update it. Nothing was sent.
503account_restartingEngineThe account's terminal is being replaced. Nothing was sent; try again in a minute.
503bad_commandEngineThe terminal refused the command, for example a negative expiration, or a history range MT5 can't select.
503terminal_errorEngineThe terminal did not give the answer asked for.
503symbol_too_largeEngineOne symbol's entry is too large for the terminal to list.
503no_priceEngineThe terminal has no price for the symbol yet (it waited 2 seconds).
503engine_busyEngineThe account's engine host has too many calls in flight (256). Nothing was done; try again.
503engine_unavailableAPIThe account's engine host is not connected to Pipsocket, or disconnected while the call waited. A trade it already had is still settled: look it up.
504terminal_timeoutEngineThe account's terminal did not answer within 5 seconds.
504engine_timeoutAPIThe account's engine did not answer within 30 seconds.

A trade call's 503 can also be a stored request the terminal didn't send ("state": "refused", with result.error saying why, such as busy when 1,000 trades are already waiting for the trade server). A ticket in the path that isn't a whole number answers 400 with no body.

MT5 retcodes

MT5's trade server return codes (MqlTradeResult.retcode), with the names the API sends in retcode_name. A code MT5 doesn't document comes back as UNKNOWN.

CodeNameMeaning
0OKThe request passed the check.
10004TRADE_RETCODE_REQUOTEThe broker requoted the price.
10006TRADE_RETCODE_REJECTThe trade server rejected the request.
10007TRADE_RETCODE_CANCELThe request was cancelled by the trader.
10008TRADE_RETCODE_PLACEDThe order was placed; execution is not confirmed yet.
10009TRADE_RETCODE_DONEThe request was completed.
10010TRADE_RETCODE_DONE_PARTIALOnly part of the request was completed.
10011TRADE_RETCODE_ERRORThe trade server could not process the request.
10012TRADE_RETCODE_TIMEOUTThe request was cancelled by a timeout.
10013TRADE_RETCODE_INVALIDThe request is invalid.
10014TRADE_RETCODE_INVALID_VOLUMEThe volume is invalid for this symbol.
10015TRADE_RETCODE_INVALID_PRICEThe price is invalid.
10016TRADE_RETCODE_INVALID_STOPSThe stop loss or take profit is invalid for this symbol or too close to the price.
10017TRADE_RETCODE_TRADE_DISABLEDTrading is disabled.
10018TRADE_RETCODE_MARKET_CLOSEDThe market is closed.
10019TRADE_RETCODE_NO_MONEYThere is not enough money for the request.
10020TRADE_RETCODE_PRICE_CHANGEDThe price changed.
10021TRADE_RETCODE_PRICE_OFFThere are no quotes to process the request.
10022TRADE_RETCODE_INVALID_EXPIRATIONThe order expiration is invalid.
10023TRADE_RETCODE_ORDER_CHANGEDThe order changed state.
10024TRADE_RETCODE_TOO_MANY_REQUESTSToo many requests in a short time.
10025TRADE_RETCODE_NO_CHANGESThe request changes nothing.
10026TRADE_RETCODE_SERVER_DISABLES_ATAutomated trading is disabled by the server.
10027TRADE_RETCODE_CLIENT_DISABLES_ATAutomated trading is disabled in the terminal.
10028TRADE_RETCODE_LOCKEDThe request is locked for processing.
10029TRADE_RETCODE_FROZENThe order or position is frozen.
10030TRADE_RETCODE_INVALID_FILLThe filling mode is not allowed for this symbol.
10031TRADE_RETCODE_CONNECTIONThere is no connection to the trade server.
10032TRADE_RETCODE_ONLY_REALThis is only allowed for live accounts.
10033TRADE_RETCODE_LIMIT_ORDERSThe account has reached its limit of pending orders.
10034TRADE_RETCODE_LIMIT_VOLUMEThe symbol has reached its volume limit for orders and positions.
10035TRADE_RETCODE_INVALID_ORDERThe order type is incorrect or not allowed.
10036TRADE_RETCODE_POSITION_CLOSEDThe position is already closed.
10038TRADE_RETCODE_INVALID_CLOSE_VOLUMEThe close volume is more than the position's volume.
10039TRADE_RETCODE_CLOSE_ORDER_EXISTA close order already exists for the position.
10040TRADE_RETCODE_LIMIT_POSITIONSThe account has reached its limit of open positions.
10041TRADE_RETCODE_REJECT_CANCELThe pending order's activation was rejected and the order cancelled.
10042TRADE_RETCODE_LONG_ONLYOnly long positions are allowed for this symbol.
10043TRADE_RETCODE_SHORT_ONLYOnly short positions are allowed for this symbol.
10044TRADE_RETCODE_CLOSE_ONLYOnly closing positions is allowed for this symbol.
10045TRADE_RETCODE_FIFO_CLOSEPositions may only be closed first in, first out.
10046TRADE_RETCODE_HEDGE_PROHIBITEDOpposite positions on one symbol are not allowed.