mt2api./ DOCUMENTATION
DEVELOPERS / API DOCUMENTATION
MT4 + MT5 / CLIENT API

Make your
first connection.

Everything you need to bring MetaTrader accounts, market data, and trading into your application.

Implementation-aware documentation

This guide follows the MT4/MT5 Client API contract, with mt2api implementation differences checked against the project reference on September 9, 2026. The endpoint catalog covers core integration workflows, not every declared compatibility endpoint. Broker and parameter support vary; consult your deployment’s /capabilities before relying on an operation.

01 / QUICKSTART

Your first request.

Open the mt2api app for account access. Send MT4 requests to https://mt4.mt2api.com and MT5 requests to https://mt5.mt2api.com. The app host is separate from the API.

  1. Prepare your environment. Install Python and requests. Set MTAPI_API_KEY on your backend. The example uses the MT5 API host.
  2. Create a session. Use ConnectEx with a demo account and the broker’s exact server name.
  3. Read your account. Store the returned token as MTAPI_SESSION_TOKEN and make the read-only request below.
Read account equity · Python
import os
import requests

# Public MT5 API. Use mt4.mt2api.com for MT4.
# Keep credentials on your backend, not in browser code.
gateway = "https://mt5.mt2api.com"
headers = {"X-Api-Key": os.environ["MTAPI_API_KEY"]}
token = os.environ["MTAPI_SESSION_TOKEN"]

response = requests.get(
    f"{gateway}/AccountSummary",
    headers=headers,
    params={"id": token},
    timeout=30,
    allow_redirects=False,
)
if response.status_code != 200 or response.headers.get("X-MtApi-Error-Code"):
    raise RuntimeError("Account request failed; verify session and API status.")

account = response.json()
if not isinstance(account, dict) or not {"equity", "currency"} <= account.keys():
    raise RuntimeError("Unexpected account response.")
print(account["equity"], account["currency"])

For MT4, use https://mt4.mt2api.com/AccountSummary. Amounts use the returned currency; do not assume USD.

02 / AUTHENTICATION

Two credentials. Different jobs.

CredentialWhere it goesPurpose
X-Api-KeyHTTP header, including WebSocket handshakeAuthenticates access to the gateway.
idQuery parameterIdentifies a connected MT4 or MT5 session.

The public API selects the platform by hostname: https://mt4.mt2api.com/AccountSummary or https://mt5.mt2api.com/AccountSummary. For a self-hosted gateway serving both platforms, use explicit /mt4 and /mt5 prefixes unless your deployment routes them by hostname.

  • Keep API keys, passwords, and tokens on your backend. Use HTTPS or a controlled local connection.
  • Compatibility login parameters contain the password in the query. Disable query logging, automatic redirects, and URL echoes in errors.
  • Encode parameters with your HTTP client. Arrays use repeated keys, not comma-separated strings.
  • Parameter names are case-sensitive. For example, expertID and stoploss must be spelled exactly.
  • MT5 identifiers are int64. Use a lossless JSON parser when handling IDs outside JavaScript’s safe integer range.
03 / CONNECTIONS

Connect once. Keep the token.

ConnectEx accepts a trading account login, password, and server name. Success returns a plain-text token, not a JSON object. Reuse it as id for account, quote, and trading calls.

Create a session · Python
# Requires: pip install requests
import os
import requests

gateway = "https://mt5.mt2api.com"
response = requests.get(
    f"{gateway}/ConnectEx",
    headers={"X-Api-Key": os.environ["MTAPI_API_KEY"]},
    params={
        "user": os.environ["MTAPI_LOGIN"],
        "password": os.environ["MTAPI_PASSWORD"],
        "server": os.environ["MTAPI_SERVER"],
        "connectTimeoutSeconds": 60,
    },
    timeout=75,
    allow_redirects=False,
)
if response.status_code != 200 or response.headers.get("X-MtApi-Error-Code"):
    raise RuntimeError("Connection failed; inspect a redacted server error.")
token = response.text.strip()  # Keep private; do not log.
if not token or "text/plain" not in response.headers.get("Content-Type", ""):
    raise RuntimeError("Unexpected connection response.")

Repeated ordinary connections can create multiple terminal sessions. Manage concurrency in your application and call Disconnect when finished.

Recovery is not revocation.

ConnectByToken needs saved encrypted credentials and persistent storage. Disconnect ends the active session but does not invalidate saved recovery credentials. The current client API has no separate token-revocation endpoint.

04 / ENDPOINT REFERENCE

Find your next request.

Core endpoints for connections, accounts, quotes, orders, history, and streaming. Select a platform or search by endpoint, parameter, or topic. All ordinary operations listed below use GET; WebSocket endpoints upgrade an authenticated GET request.

35 endpointsCORE CLIENT API
GET/ConnectExConnect using the exact broker server name.MT4MT5
GET https://mt4.mt2api.com/ConnectExGET https://mt5.mt2api.com/ConnectEx

Connections · requires X-Api-Key

ParameterType / requirementDescription
userinteger · requiredMT4 int32 / MT5 int64 account login.
passwordstring · requiredTrading account password.
serverstring · requiredTrading server name, not a broker website URL.
connectTimeoutSecondsinteger1–300 seconds. Defaults: MT4 30, MT5 60.

Success response

text/plain session token.

Encode query values. Disable query logging and redirects; never expose the password in client-side website code.
GET/ConnectConnect using a broker trading-server address.MT4MT5
GET https://mt4.mt2api.com/ConnectGET https://mt5.mt2api.com/Connect

Connections · requires X-Api-Key

ParameterType / requirementDescription
userinteger · requiredMT4 int32 / MT5 int64 account login.
passwordstring · requiredAccount password.
hoststring · requiredTrading-server host, without scheme or path.
portinteger · requiredSubmit explicitly, even for port 443.

Success response

text/plain session token.

MT5 address login requires a supported terminal configuration and build. Verified scope is limited; server-name ConnectEx is the recommended starting point.
GET/ConnectByTokenRestore a session from saved connection information.MT4MT5
GET https://mt4.mt2api.com/ConnectByTokenGET https://mt5.mt2api.com/ConnectByToken

Connections · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
connectTimeoutSecondsintegerConnection timeout, 1–300 seconds.

Success response

Session token.

Recovery requires encrypted connection records and persistent storage. An active worker returns its existing token. This is not trade retry or idempotency.
GET/DisconnectClose the active account session and its subscriptions.MT4MT5
GET https://mt4.mt2api.com/DisconnectGET https://mt5.mt2api.com/Disconnect

Connections · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

JSON string "OK".

Disconnect removes the active session, but does not revoke saved token recovery credentials.
GET/ConnectionStatusRead connection state by probing the terminal worker.MT4MT5
GET https://mt4.mt2api.com/ConnectionStatusGET https://mt5.mt2api.com/ConnectionStatus

Connections · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

Connection status object.

MT5 may use saved credentials to reconnect during this check; it is not a cached local property read.
GET/AccountSummaryRead account balance, equity, margin, and currency.MT4MT5
GET https://mt4.mt2api.com/AccountSummaryGET https://mt5.mt2api.com/AccountSummary

Accounts · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

{ balance, credit, equity, margin, freeMargin, profit, marginLevel, leverage, currency, type }. MT5 also includes method and synced.

GET/AccountDetailsRead account identity, broker information, and available trading permissions.MT4MT5
GET https://mt4.mt2api.com/AccountDetailsGET https://mt5.mt2api.com/AccountDetails

Accounts · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

Account details including user, accountName, serverName, company, currency, and accountLeverage.

The mt2api extension contains permission snapshots. A true permission snapshot does not guarantee a future order will be accepted.
GET/SymbolListList symbol names available on the connected account.MT4MT5
GET https://mt4.mt2api.com/SymbolListGET https://mt5.mt2api.com/SymbolList

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

string[] of broker-specific symbol names.

Use actual broker suffixes. Do not assume EURUSD exists under the same name at every broker.
GET/SymbolParamsRead symbol details such as price increments and lot limits.MT4MT5
GET https://mt4.mt2api.com/SymbolParamsGET https://mt5.mt2api.com/SymbolParams

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact broker symbol.

Success response

Platform-specific symbol metadata.

MT4: symbol.minLot/maxLot/lotStep. MT5: symbolGroup.minLots/maxLots/lotsStep. tickSize is already a price increment.
GET/QuoteRead one MT4 quote.MT4
GET https://mt4.mt2api.com/Quote

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact symbol name.
msNotOlderintegerFreshness requirement in milliseconds. Default 0 allows an older synchronized tick.

Success response

{ symbol, bid, ask, time }.

time is a broker-calendar string. A positive freshness limit may fail if the worker cannot obtain fresh observations.
GET/GetQuoteRead one MT5 quote.MT5
GET https://mt5.mt2api.com/GetQuote

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact symbol name.
msNotOlderintegerFreshness requirement in milliseconds; default 0.

Success response

{ symbol, bid, ask, time, last, volume }.

A Z suffix on MT5 time does not currently establish that broker time was normalized to true UTC.
GET/GetQuoteManyRead quotes for several symbols in request order.MT4MT5
GET https://mt4.mt2api.com/GetQuoteManyGET https://mt5.mt2api.com/GetQuoteMany

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolsstring[] · requiredRepeat symbols in the query: symbols=EURUSD&symbols=GBPUSD.
msNotOlderintegerFreshness requirement; default 0.

Success response

Quote[] in request order.

A failed symbol is not returned as a partially successful quote array.
GET/QuoteHistoryRead historical MT4 bars backwards from a starting time.MT4
GET https://mt4.mt2api.com/QuoteHistory

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact symbol name.
timeframeenum · requiredM1, M5, M15, M30, H1, H4, D1, W1, MN1.
fromstring · requiredBroker-calendar start time.
countinteger · requiredNumber of bars.

Success response

Bar[] with open, high, low, close, time, volume, tickVolume, spread.

GET/PriceHistoryRead MT5 bars in an explicit time range.MT5
GET https://mt5.mt2api.com/PriceHistory

Market data · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact symbol name.
from / tostring · requiredExplicit broker-calendar range.
timeFrameinteger · requiredTimeframe in minutes; note capital F.
timeoutSecondsintegerDefault 30; 1–300.

Success response

Bar[] with openPrice, highPrice, lowPrice, closePrice, time, volume, tickVolume, spread.

GET/OpenedOrdersRead current positions and pending orders together.MT4MT5
GET https://mt4.mt2api.com/OpenedOrdersGET https://mt5.mt2api.com/OpenedOrders

Orders · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
sortMT5 integerMT5 only: 0 opening time (default), 1 closing time.
ascendingMT5 booleanMT5 only: default true.

Success response

Order[].

MT4 uses string type values; MT5 uses integer orderType. Classify positions and pending orders explicitly.
GET/OpenedOrderRead one current position or pending order.MT4MT5
GET https://mt4.mt2api.com/OpenedOrderGET https://mt5.mt2api.com/OpenedOrder

Orders · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketinteger · requiredCurrent order/position ticket: int32 for MT4, int64 for MT5.

Success response

Order object.

GET/OrderSendSubmit an MT4 market or pending order.MT4
GET https://mt4.mt2api.com/OrderSend

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact broker symbol.
operationenum · requiredBuy, Sell, BuyLimit, SellLimit, BuyStop, SellStop.
volumenumber · requiredOpening size in lots.
placedTypeenum · explicitUse Expert. The contract default Client is unsupported.
price / slippagenumber / int32Default 0. Pending orders need an actual price. Slippage is in points.
stoploss / takeprofitnumberDefault 0 means no stop or target.
magic / commentint32 / stringOptional strategy tags; magic defaults to 0.

Success response

Order object.

State-changing GET. Never automatically retry an uncertain trade result. OrderSendTask uses the same MT4 parameter model.
GET/OrderSendTaskSubmit an MT5 market or pending order.MT5
GET https://mt5.mt2api.com/OrderSendTask

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact broker symbol.
operationinteger · required0 Buy, 1 Sell, 2 BuyLimit, 3 SellLimit, 4 BuyStop, 5 SellStop, 6 BuyStopLimit, 7 SellStopLimit.
volumenumber · requiredOpening size in lots.
price / slippagenumber / int64Default 0. Pending price must be positive; slippage in points.
stoploss / takeprofitnumberDefault 0 means no stop or target.
expertIDint64Strategy identifier, default 0. Exact spelling matters.
stopLimitPricenumberRequired positive value for stop-limit orders.
expirationType / expirationinteger / string0 GTC, 1 Day, 2 Specified, 3 SpecifiedDay. Default 2 without expiration uses GTC for new pending orders.
placedTypeintegerOnly 0 is supported.

Success response

Order object; inspect fills and reconcile against positions/deals.

MT5 has no OrderSend endpoint. Task waits for a result; it does not return a background job ID.
GET/OrderModifyModify an MT4 order.MT4
GET https://mt4.mt2api.com/OrderModify

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint32 · requiredCurrent order ticket.
stoploss / takeprofitnumber · requiredPass current values to preserve them; zero removes them.
pricenumberExplicitly use the desired pending price or current openPrice.
expirationstringOptional expiration.

Success response

Order object.

MT4 price=0 is sent into the native modify call; it does not automatically preserve the current price.
GET/OrderModifyTaskModify an MT5 position or pending order.MT5
GET https://mt5.mt2api.com/OrderModifyTask

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint64 · requiredCurrent position/pending-order ticket.
stoploss / takeprofitnumber · requiredPass current values to preserve them.
price / stoplimitnumberDefault 0. Explicitly preserve the stop-limit price when needed.
expirationType / expirationinteger / stringChoose the broker-supported expiry policy.

Success response

Order object.

Modification uses stoplimit, while sending uses stopLimitPrice.
GET/OrderCloseClose an MT4 market position.MT4
GET https://mt4.mt2api.com/OrderClose

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint32 · requiredCurrent market-order ticket.
lotsnumberDefault 0 closes the full position.
price / slippagenumber / int32Default 0; slippage is in points.

Success response

Order object.

Pending orders must be deleted, not closed.
GET/OrderCloseTaskClose an MT5 position.MT5
GET https://mt5.mt2api.com/OrderCloseTask

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint64 · requiredCurrent position ticket, not the position identifier.
lotsnumberDefault 0 closes the full position.
price / slippagenumber / int64Default 0; slippage in points.
commentstringOptional comment.

Success response

Order object.

Partial closes must meet lot increments and leave a valid remaining volume.
GET/OrderDeleteCancel an MT4 pending order.MT4
GET https://mt4.mt2api.com/OrderDelete

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint32 · requiredPending-order ticket.

Success response

JSON string "OK".

Does not close a market position.
GET/OrderCancelTaskCancel an MT5 pending order.MT5
GET https://mt5.mt2api.com/OrderCancelTask

Trading · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint64 · requiredPending-order ticket.
lotsnumberUse 0 for full cancellation; partial cancellation is unsupported.
commentstringOptional comment.

Success response

Historical pending Order object, not "OK".

GET/ClosedOrdersRead recently closed orders associated with the session.MT4MT5
GET https://mt4.mt2api.com/ClosedOrdersGET https://mt5.mt2api.com/ClosedOrders

History · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

Order[], up to 100 recent records.

This is not a complete history or reconciliation endpoint.
GET/OrderHistoryRead order history for an explicit broker-calendar range.MT4MT5
GET https://mt4.mt2api.com/OrderHistoryGET https://mt5.mt2api.com/OrderHistory

History · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
fromstring · requiredRange start.
tostring · explicitRequired for MT5. Always submit it on MT4 as well.
sort / ascendingMT5 integer / booleanMT5 defaults: 0 / true.
filterMT5 string[]Optional MT5 field filter using repeated keys.

Success response

MT4: Order[]. MT5: { orders, internalDeals, internalOrders, action, partialResponse }.

MT5 orders are position summaries, not period cash flows. Reconcile internalDeals by deal ticket. History is limited to what the broker/terminal provides.
GET/OrderHistoryPaginationRead a numbered page of history.MT4MT5
GET https://mt4.mt2api.com/OrderHistoryPaginationGET https://mt5.mt2api.com/OrderHistoryPagination

History · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
from / tostring · explicitBroker-calendar range; always provide both.
ordersPerPageinteger · requiredPositive page size.
pageNumberinteger · requiredZero-based page number.
requestAgainbooleanDefault false; true refreshes the MT5 range cache.

Success response

MT4: Order[]. MT5: { pagesCount, pageNumber, orders }.

Pagination does not guarantee that all history has been loaded by the terminal.
GET/HistoryDealsByPositionIdRead deals associated with a position identifier.MT5
GET https://mt5.mt2api.com/HistoryDealsByPositionId

History · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
ticketint64 · requiredThe position identifier, not necessarily the current position ticket.

Success response

DealInternal[].

Use Order.mt2api.positionIdentifier from a current MT5 position when present. Do not substitute another ticket type without evidence.
GET/SubscribeSubscribe a session to a symbol before opening OnQuote.MT4MT5
GET https://mt4.mt2api.com/SubscribeGET https://mt5.mt2api.com/Subscribe

Streaming · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredExact broker symbol.
intervalintegerMilliseconds; default 0 adds no explicit throttle.

Success response

Subscription acknowledgement.

Sampling and worker scheduling still apply; interval=0 is not a lossless tick-stream guarantee.
GET/SubscribeManySubscribe to several broker symbols.MT4MT5
GET https://mt4.mt2api.com/SubscribeManyGET https://mt5.mt2api.com/SubscribeMany

Streaming · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolsstring[] · explicitRepeat symbols keys. Required on MT5; omitting on MT4 means all symbols.
intervalintegerMilliseconds; default 0.
replace / forceplatform-specific booleanMT4 replace=false. MT5 force=false currently has no worker behavior difference.

Success response

Subscription acknowledgement.

A partial failure may leave some subscriptions active. Check SubscribedSymbols.
GET/SubscribedSymbolsRead the session’s explicitly subscribed symbols.MT4MT5
GET https://mt4.mt2api.com/SubscribedSymbolsGET https://mt5.mt2api.com/SubscribedSymbols

Streaming · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

string[].

GET/UnSubscribeRemove one explicit symbol subscription.MT4MT5
GET https://mt4.mt2api.com/UnSubscribeGET https://mt5.mt2api.com/UnSubscribe

Streaming · requires X-Api-Key

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.
symbolstring · requiredSymbol to remove.

Success response

Unsubscribe acknowledgement.

WS/OnQuoteReceive quote events over an authenticated WebSocket.MT4MT5
WS wss://mt4.mt2api.com/OnQuoteWS wss://mt5.mt2api.com/OnQuote

Streaming · requires X-Api-Key on the WebSocket handshake

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

{ type: "Quote", id, timestampUTC, data: Quote }.

timestampUTC is gateway-send time in Unix milliseconds. Socket queues are bounded; reconnecting clients must resynchronize. Closing the socket does not remove explicit symbol subscriptions.
WS/OnOrderUpdateReceive sampled account and order snapshots.MT4MT5
WS wss://mt4.mt2api.com/OnOrderUpdateWS wss://mt5.mt2api.com/OnOrderUpdate

Streaming · requires X-Api-Key on the WebSocket handshake

ParameterType / requirementDescription
idstring · requiredSession token returned by ConnectEx or Connect.

Success response

type="OrderUpdate". MT4 data includes orders; MT5 includes openedOrders and user.

These are sampled snapshots, not guaranteed delivery of every intermediate trade state. No replay offset is promised.

Parameters shown cover the common integration surface. Optional aliases and advanced compatibility methods are not exhaustively listed. Platform-specific behavior in this guide takes precedence over assumptions based on a similar method name.

05 / WEBSOCKETS

Subscribe. Then stream.

Call Subscribe or SubscribeMany over HTTP, then connect to wss://mt5.mt2api.com/OnQuote?id=… using WebSocket. Use wss: for a gateway served over HTTPS.

The handshake requires X-Api-Key. Native browser WebSocket cannot set that header; connect from your backend with a client such as Node.js ws. Do not place the API key in the URL to work around this.

Subscribe and stream · Node.js
// Node.js; install the ws package. Do not run in a browser.
import WebSocket from 'ws';
const { MTAPI_API_KEY, MTAPI_SESSION_TOKEN } = process.env;
const gateway = 'https://mt5.mt2api.com';
const subscribe = new URL('/Subscribe', gateway);
subscribe.searchParams.set('id', MTAPI_SESSION_TOKEN);
subscribe.searchParams.set('symbol', 'EURUSD'); // Use your broker's symbol.
const response = await fetch(subscribe, {
  headers: { 'X-Api-Key': MTAPI_API_KEY },
  redirect: 'error',
  signal: AbortSignal.timeout(30_000),
});
if (response.status !== 200 || response.headers.has('X-MtApi-Error-Code')) {
  throw new Error('Subscription failed.');
}
const url = new URL('/OnQuote', gateway);
url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
url.searchParams.set('id', MTAPI_SESSION_TOKEN);
const socket = new WebSocket(url, {
  headers: { 'X-Api-Key': MTAPI_API_KEY },
});
socket.on('message', (raw) => {
  try {
    const event = JSON.parse(raw.toString());
    if (event.type === 'Quote' && event.data) {
      console.log(event.data.symbol, event.data.bid, event.data.ask);
    } else {
      console.warn('Non-quote event; inspect and resynchronize as needed.');
    }
  } catch {
    console.warn('Invalid event; resynchronize before continuing.');
  }
});
socket.on('error', () => console.error('Stream error; check session.'));
socket.on('close', () => console.warn('Stream closed; resynchronize before reconnecting.'));
// On shutdown, close the socket AND call UnSubscribe or Disconnect.

Quote event · schema illustration
{
  "type": "Quote",
  "id": "<SESSION_TOKEN>",
  "timestampUTC": 0,
  "data": {
    "symbol": "<BROKER_SYMBOL>",
    "bid": 0,
    "ask": 0,
    "time": "<BROKER_TIME>"
  }
}

Zeros above illustrate field types, not actual quotes. timestampUTC is the gateway’s frame-send time in Unix milliseconds. data.time is the broker quote time and may have different timezone semantics.

  • Each socket has a bounded 512-event queue; a slow consumer can be disconnected.
  • Order events are sampled snapshots. Intermediate states can be missed; there is no replay or sequence-offset guarantee.
  • After a disconnect, refresh accounts, positions, pending orders, and relevant history before resuming.
  • Closing the socket does not remove explicit symbol subscriptions. Call UnSubscribe or Disconnect when finished.
06 / TRADING

Respect the platform differences.

Trading GET requests change account state.

Disable automatic retries for order submission, modification, cancellation, and closing in HTTP clients, proxies, and job queues. A timeout may occur after the broker accepts a request. Reconcile before deciding what to do next.

OperationMT4MT5
PlaceOrderSendOrderSendTask
ModifyOrderModifyOrderModifyTask
CloseOrderCloseOrderCloseTask
Cancel pendingOrderDeleteOrderCancelTask
Buy / SellBuy / Sell strings0 / 1 integers
Order sourceExplicit placedType=ExpertOnly placedType=0
  • Opening size uses volume; closing size uses lots. lots=0 closes all current volume.
  • Slippage is in points, not pips. Validate lot size and increments against the actual broker symbol.
  • For modifications, submit existing stop-loss and take-profit values if preserving them. Zero clears them.
  • MT5 Task and Safe methods do not provide durable idempotency. OrderSendSafe does not accept expertID.
  • MT5 current position tickets, position identifiers, pending-order tickets, and deal tickets are different concepts. Use the current ticket for closing and the position identifier for deal lookup.
  • A successful response may reflect a partial fill. Reconcile requested volume, current positions, and deals.
07 / ERRORS & RECOVERY

Check more than the status code.

Ordinary API errors default to HTTP 201 and carry X-MtApi-Error-Code. A successful-looking HTTP status or MT5 code: 0 does not establish success. Inspect the error header, HTTP status, error-shaped body, and expected success structure.

Error response · schema illustration
HTTP/1.1 201 Created
Content-Type: text/json
X-MtApi-Error-Code: TRADE_RESULT_UNKNOWN

{
  "message": "<REDACTED_ERROR_MESSAGE>",
  "stackTrace": null,
  "nodeName": "<NODE>",
  "user": 0,
  "code": 0
}

Error / conditionHow to handle it
INVALID_PARAM, INVALID_PARAMETERCorrect the request before sending again.
INVALID_TOKEN, NO_CONNECTION, CONNECT_ERRORVerify the session and account identity; stop sending new trades.
UNSUPPORTED_OPERATION, UNSUPPORTED_PARAMETERCheck deployment capabilities. Do not silently substitute a different operation.
TIMEOUT, STALE_QUOTE, NO_QUOTESFor reads, apply your retry policy; never present an old quote as fresh.
TRADE_RESULT_UNKNOWN, TRADE_TIMEOUT, lost responseThe broker may have acted. Reconcile orders and deals before any new trade attempt.
HTTP 401 / 501Usually gateway authentication failure / unsupported operation. Read the error response.

MT4 ordinary error bodies contain message, stackTrace, code. MT5 additionally includes nodeName, user. Log only redacted context. An empty history result after a connection failure does not prove a trade was never executed.

08 / COMPATIBILITY

Build against verified behavior.

Core demo workflows have been exercised on IC Markets MT4 and MT5. IG MT4 has read-only connection evidence, while trading was rejected in documented tests. That does not establish support for every broker, instrument, account mode, or parameter combination.

  • /healthz checks gateway liveness. /readyz checks terminal configuration; it does not prove a broker login or trading permission.
  • /capabilities describes deployment limits. Declared routes and static implementation coverage are not acceptance evidence.
  • MT5 timestamps may carry Z without full broker-time normalization. Use explicit, verified broker-calendar ranges for history.
  • MT4 history is limited to loaded terminal history. MT5 history depends on broker and SDK availability. ClosedOrders is not a full reconciliation source.
  • OTP/certificate login, general proxy support, broker account creation, and several statistics and timezone functions remain incomplete.
  • The self-hosted implementation requires MetaTrader terminal templates inside Docker. Connection capacity depends on infrastructure and workload.
Start your integration