# FxSocket documentation > FxSocket is a cloud API for MetaTrader 4 and MetaTrader 5. Every connected broker account gets its own dedicated MT4 or MT5 terminal in FxSocket's cloud, controlled through a REST API and a WebSocket stream from Python, Node.js, or any language that speaks HTTP. This file is every page of https://fxsocket.com/docs in one Markdown document, for AI agents and LLM tools. The index with product facts is https://fxsocket.com/llms.txt. Each page is also served on its own at its URL plus .md. --- # FxSocket API Documentation Source: https://fxsocket.com/docs FxSocket gives every connected trading account its own dedicated cloud terminal, with a REST API and a WebSocket stream. Pick your platform to dive into the reference, or go straight to the platform-wide API for multi-account execution and billing. cTrader support is on the roadmap and is not available yet. Every page below is also available as one file: https://fxsocket.com/llms-full.txt ## MetaTrader 5 - [Overview](https://fxsocket.com/docs/mt5.md) - [Authentication](https://fxsocket.com/docs/mt5/authentication.md): API keys: header or query parameter. - [Managing Accounts](https://fxsocket.com/docs/mt5/accounts.md): Link, list, and remove accounts via /v1. - [Account Data](https://fxsocket.com/docs/mt5/account-data.md): Balances, positions, history, and connection status. - [Market Data](https://fxsocket.com/docs/mt5/market-data.md): Symbols, quotes, price history, and contract specs. - [Trading](https://fxsocket.com/docs/mt5/trading.md): Place, modify, and close orders. - [WebSocket Streams](https://fxsocket.com/docs/mt5/websocket.md): Live ticks, bars, positions, and trades. - [Errors & Rate Limits](https://fxsocket.com/docs/mt5/errors.md): Error envelope, status codes, and rate limits. ## MetaTrader 4 - [Overview](https://fxsocket.com/docs/mt4.md) - [Authentication](https://fxsocket.com/docs/mt4/authentication.md): API keys: header or query parameter. - [Managing Accounts](https://fxsocket.com/docs/mt4/accounts.md): Link, list, and remove accounts via /v1. - [Account Data](https://fxsocket.com/docs/mt4/account-data.md): Balances, positions, history, and connection status. - [Market Data](https://fxsocket.com/docs/mt4/market-data.md): Symbols, quotes, price history, and contract specs. - [Trading](https://fxsocket.com/docs/mt4/trading.md): Place, modify, and close orders. - [WebSocket Streams](https://fxsocket.com/docs/mt4/websocket.md): Live ticks, bars, positions, and trades. - [Errors & Rate Limits](https://fxsocket.com/docs/mt4/errors.md): Error envelope, status codes, and rate limits. ## Platform API The /v1 layer above the terminals: send one order to many accounts, close across them by selector, and top up the prepaid balance that renews them. Works across MT4 and MT5 in the same call. - [Overview](https://fxsocket.com/docs/api.md) - [Multi-account execution](https://fxsocket.com/docs/api/batch-orders.md): One order to many accounts, and selector-based closes across them. - [Balance & top-ups](https://fxsocket.com/docs/api/wallet.md): Prepaid balance, crypto top-ups, seats and upcoming charges. ## AI agents - [MCP server for AI agents](https://fxsocket.com/docs/mcp.md): let Claude, Cursor, VS Code or any MCP client read your MT4 and MT5 accounts. Read-only, remote or as a Docker image. - [Docs for AI coding agents](https://fxsocket.com/docs/ai-agents.md): a rules file for your project, Markdown docs and llms-full.txt. --- # MetaTrader 5 REST & WebSocket API Source: https://fxsocket.com/docs/mt5 FxSocket exposes each connected MetaTrader 5 account through a REST API and a WebSocket stream. Every account gets its own dedicated MT5 terminal in our cloud. Requests to your account hit your own terminal, nobody shares it. All endpoints return JSON. Per-account base URL: `https://api.fxsocket.com/mt5/{account_id}` `{account_id}` is the UUID of your connected MT5 account. Copy it from the Accounts page (https://app.fxsocket.com/dashboard/accounts) or read it from GET https://api.fxsocket.com/v1/accounts. Your API key lives on the API Key page (https://app.fxsocket.com/dashboard/api-key). You can link, list, and remove accounts from the dashboard, or programmatically through the account-management API at `https://api.fxsocket.com/v1`. See [Managing Accounts](https://fxsocket.com/docs/mt5/accounts.md). ## Explore the MT5 API - [Authentication](https://fxsocket.com/docs/mt5/authentication.md): API keys: header or query parameter. - [Managing Accounts](https://fxsocket.com/docs/mt5/accounts.md): Link, list, and remove accounts via /v1. - [Account Data](https://fxsocket.com/docs/mt5/account-data.md): Balances, positions, history, and connection status. - [Market Data](https://fxsocket.com/docs/mt5/market-data.md): Symbols, quotes, price history, and contract specs. - [Trading](https://fxsocket.com/docs/mt5/trading.md): Place, modify, and close orders. - [WebSocket Streams](https://fxsocket.com/docs/mt5/websocket.md): Live ticks, bars, positions, and trades. - [Errors & Rate Limits](https://fxsocket.com/docs/mt5/errors.md): Error envelope, status codes, and rate limits. ## SDKs & Generated Clients The official FxSocket SDKs wrap this API (account management, trading, market data, and live WebSocket streams) with typed models for MT4 and MT5: - Python: `pip install fxsocket`, sync and async clients. PyPI: https://pypi.org/project/fxsocket/ · GitHub: https://github.com/fxsocket-com/FxSocket-Python-SDK - Node.js / TypeScript: `npm install @fxsocket/sdk`, ESM and CommonJS. npm: https://www.npmjs.com/package/@fxsocket/sdk · GitHub: https://github.com/fxsocket-com/FxSocket-Node-SDK Using another language? The API is plain HTTP and JSON, and every account serves its own live OpenAPI 3 spec, so you can generate a typed client for any language instead: - Swagger UI: `https://api.fxsocket.com/mt5/{account_id}/swagger-ui/`: browsable, per-account interactive docs (keep the trailing slash). No API key needed. - Raw spec: `https://api.fxsocket.com/mt5/{account_id}/api-doc/openapi.json`: point any OpenAPI generator (openapi-generator, openapi-typescript, oapi-codegen, ...) at this URL. These two routes (plus `/`) are the only ones served without an API key. --- # MetaTrader 5 API Authentication Source: https://fxsocket.com/docs/mt5/authentication Every FxSocket API request is authenticated with a per-user API key, passed as an X-API-Key header, or as an api_key query parameter for clients (like WebSocket) that can't set headers. There is no OAuth dance or Bearer scheme to manage, and your key only works against your own MetaTrader 5 accounts. ### Header X-API-Key: fxs_live_... Every request needs your fxsocket API key: copy it from the dashboard's API Key page. Keys are per-user and only work on your own accounts: authentication is enforced by your own dedicated terminal, and a valid key used against someone else's account_id still gets a 401. 401 response: ```json { "error": "MRPC_UNAUTHORIZED", "message": "missing or invalid API key (X-API-Key header or api_key query parameter)" } ``` ### Query ?api_key=fxs_live_... Alternative to the header, and the only method WebSocket clients can use. The key is the same in both cases. There is no Bearer / Authorization scheme. Rotating your key from the dashboard propagates to your terminals within about 5 minutes. The terminal restarts briefly when the new key lands, so a short window of 5xx responses right after a rotation is normal. ## Related - [Managing Accounts](https://fxsocket.com/docs/mt5/accounts.md) - [Account Data](https://fxsocket.com/docs/mt5/account-data.md) - [Errors & Rate Limits](https://fxsocket.com/docs/mt5/errors.md) --- # MT5 Account Management API Source: https://fxsocket.com/docs/mt5/accounts Link, list, and remove MetaTrader 5 accounts programmatically with the account-management API. Linking an account provisions its own dedicated MT5 terminal in our cloud and returns the account_id you'll use across every per-account REST and WebSocket route. Base URL: `https://api.fxsocket.com/v1` Link, list, and remove MT5 accounts programmatically. These endpoints live under a different base URL (https://api.fxsocket.com/v1) and use the same X-API-Key authentication. Linking an account provisions its own dedicated terminal; once its status reads "connected" you can drive it through the per-account REST and WebSocket API documented below. ### GET /v1/accounts List every MT5 account linked to your API key. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts ``` Response: ```json [{ "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt5", "server": "VTMarkets-Demo", "login": 1234567, "status": "connected", "error": "", "created_at": "2026-06-13T22:52:23Z" }] ``` ### POST /v1/accounts Link a new MT5 account and provision its terminal. The response comes back with status "connecting". Poll GET /v1/accounts/{account_id} until it reads "connected" (usually 1–3 minutes). Returns 402 if you're at your plan's account limit, 409 if the account is already linked, or 400 if the broker rejects the login. MT5 only. Parameters: - `server` (required): Broker server name, exactly as MT5 shows it (e.g. VTMarkets-Demo). - `login` (required): MT5 account login number. - `password` (required): Account password (investor or master). Stored encrypted; never returned. - `nickname`: Optional label shown in the dashboard. Request body: ```json { "server": "VTMarkets-Demo", "login": 1234567, "password": "your-account-password", "nickname": "my demo" } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/v1/accounts \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"server":"VTMarkets-Demo","login":1234567,"password":"your-account-password","nickname":"my demo"}' ``` 201 response: ```json { "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt5", "server": "VTMarkets-Demo", "login": 1234567, "status": "connecting", "error": "", "created_at": "2026-06-13T22:52:23Z" } ``` ### GET /v1/accounts/{account_id} Fetch a single account by id, to poll status after linking, until it turns "connected". Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts/{account_id} ``` Response: ```json { "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt5", "server": "VTMarkets-Demo", "login": 1234567, "status": "connected", "error": "", "created_at": "2026-06-13T22:52:23Z" } ``` ### DELETE /v1/accounts/{account_id} Unlink an account: disconnects it, tears down its dedicated terminal, and removes it, freeing the account slot on your plan. Returns 204 No Content with an empty body. Example request: ```bash curl -X DELETE \ -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts/{account_id} ``` Response: ``` 204 No Content ``` status is the account's overall health: "connecting" while its terminal is still starting up (typically 1–3 minutes after linking), "connected" once it's logged in and serving data, "error" if provisioning or the broker login failed (see the error field), and "disconnected" otherwise. The id returned here is the {account_id} used in every per-account route below. ## Related - [Authentication](https://fxsocket.com/docs/mt5/authentication.md) - [Account Data](https://fxsocket.com/docs/mt5/account-data.md) - [Trading](https://fxsocket.com/docs/mt5/trading.md) --- # MetaTrader 5 Account Data & Status API Source: https://fxsocket.com/docs/mt5/account-data Read live and static state for a connected MetaTrader 5 account: balance and equity, the static account configuration, open positions and pending orders, trade and position history, and a single connection-health endpoint to confirm the account is logged in and trading-ready. Base URL: `https://api.fxsocket.com/mt5/{account_id}` ### GET /mt5/{account_id}/AccountSummary Snapshot of the connected trading account: balance, credit, floating profit, equity, margin, free margin, margin level, leverage, account currency, and account type. Reflects broker-side state at call time, no caching. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/AccountSummary ``` Response: ```json { "balance": 9686.15, "credit": 0.0, "profit": 0.0, "equity": 9686.15, "margin": 0.0, "freeMargin": 9686.15, "marginLevel": 0.0, "leverage": 400, "currency": "USD", "type": "Demo" } ``` ### GET /mt5/{account_id}/AccountInfo Static identity and configuration of the account: the who-and-how that rarely changes, as opposed to the live financials in /AccountSummary. Includes the account holder name, login, broker company and server, currency, leverage, account type, margin mode (Netting / Hedging / Exchange, needed to know whether an opposite order nets a position or opens a new one), stop-out configuration, and trade permissions. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/AccountInfo ``` Response: ```json { "name": "Lars Joeressen", "login": 2100152454, "server": "TegasFX-Demo", "company": "TegasFX Ltd", "currency": "USD", "currencyDigits": 2, "leverage": 200, "type": "Demo", "marginMode": "Hedging", "marginSoMode": "Percent", "marginCallLevel": 100.0, "stopOutLevel": 70.0, "tradeAllowed": true, "tradeExpert": true, "limitOrders": 200, "fifoClose": false } ``` ### GET /mt5/{account_id}/OpenedOrders All open positions and active pending orders: one row per position (already-filled trade) and one per pending order (limit / stop / stop-limit). kind discriminates the two; pending orders show their trigger price in openPrice and carry zero swap/profit. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/OpenedOrders ``` Response: ```json [{ "ticket": 211438758, "symbol": "USDJPY", "type": "Sell", "kind": "position", "lots": 0.1, "openPrice": 160.505, "currentPrice": 160.547, "stopLoss": 160.576, "takeProfit": 160.458, "swap": 0.0, "profit": -2.62, "magic": 0, "comment": "", "openTime": "2026-06-11T11:02:04.000Z" }, { "ticket": 211583734, "symbol": "GBPUSD", "type": "BuyStop", "kind": "pending", "lots": 0.01, "openPrice": 1.34958, "currentPrice": 1.33683, "stopLoss": 1.34611, "takeProfit": 1.35275, "swap": 0.0, "profit": 0.0, "magic": 0, "comment": "", "openTime": "2026-06-10T09:30:00.000Z" }] ``` ### GET /mt5/{account_id}/OrderHistory Closed deals in a time range. Returns DEAL entries (executions), not ORDER entries; pending orders that never filled don't appear here. Omit both bounds to fetch all-time history. Parameters: - `from`: Inclusive lower bound (broker server time). ISO-8601 (2026-01-01T00:00:00Z) or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/OrderHistory?from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "ticket": 211438992, "order": 211438991, "symbol": "EURUSD", "type": "Sell", "entry": "Out", "volume": 0.1, "price": 1.15410, "commission": -0.40, "swap": 0.0, "profit": 12.00, "magic": 0, "comment": "", "time": "2026-06-10T15:42:11Z" }] ``` ### GET /mt5/{account_id}/PositionHistory Closed positions in a time range: one row per round-trip trade (open → close), reconstructed from the underlying deals with volume-weighted open/close prices. Use this when you want net results per position; use /OrderHistory when you need the raw deal log. Omit both bounds to fetch all-time history. Parameters: - `from`: Inclusive lower bound (broker server time). ISO-8601 (2026-01-01T00:00:00Z) or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/PositionHistory?from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "positionId": 211438758, "symbol": "EURUSD", "type": "Buy", "volume": 0.1, "openTime": "2026-06-10T09:12:04.000Z", "openPrice": 1.15201, "closeTime": "2026-06-10T15:42:11.000Z", "closePrice": 1.15410, "profit": 20.90, "swap": 0.0, "commission": -0.80, "netProfit": 20.10, "magic": 0, "comment": "" }] ``` ### GET /mt5/{account_id}/status Full connection health of the terminal, in one call: is the terminal alive, is it connected to the broker, and is the account logged in? Use this to confirm an account is live and trading-ready before sending orders. Always returns HTTP 200; read the body to see the actual state. The top-level status is ready (everything healthy and the account logged in), starting (still booting / logging in), degraded (e.g. broker disconnected), or down. For lightweight probes there are also two unauthenticated routes that signal via HTTP status code: GET /healthz (200 once fully ready, 503 otherwise) and GET /livez (200 while the terminal is alive, regardless of broker connection). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/status ``` Response: ```json { "status": "ready", "terminal": { "alive": true, "build": 5180, "pingMs": 42 }, "broker": { "connected": true, "server": "TegasFX-Demo" }, "account": { "loggedIn": true, "login": 2100152454, "currency": "USD", "type": "Demo", "tradeAllowed": true }, "bridge": { "version": "0.2.0", "tradeEaReady": true, "symbolsSynced": true }, "serverTime": "2026-06-11T08:55:57.000Z" } ``` ## Related - [Trading](https://fxsocket.com/docs/mt5/trading.md) - [Market Data](https://fxsocket.com/docs/mt5/market-data.md) - [WebSocket Streams](https://fxsocket.com/docs/mt5/websocket.md) --- # MetaTrader 5 Market Data API Source: https://fxsocket.com/docs/mt5/market-data Pull MetaTrader 5 market data over REST: the broker's symbol list, latest quotes, full contract specifications, OHLC price history for any timeframe, and broker server time. For a continuous tick feed, use the WebSocket prices stream instead of polling. Base URL: `https://api.fxsocket.com/mt5/{account_id}` ### GET /mt5/{account_id}/symbols Names of all symbols available in Market Watch. Use the returned names verbatim with /getQuote, /SymbolInfo, /PriceHistory, and /OrderSend. Many brokers suffix their symbols (EURUSD.sd, XAUUSD.r), so discover the exact spelling here instead of assuming plain names. A symbol not in Market Watch can't stream ticks until it's added; a getQuote call enables it on demand. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/symbols ``` Response: ```json ["EURUSD.sd", "GBPUSD.sd", "USDJPY.sd", "XAUUSD.sd", "..."] ``` ### GET /mt5/{account_id}/getQuote Latest tick for a symbol: the most recent bid, ask, last, volume, and broker server time. If the symbol isn't yet in Market Watch it's enabled on demand, which may add a small delay on the first call. For continuous ticks use the WebSocket prices topic instead. Parameters: - `symbol` (required): Symbol name as listed by /symbols (e.g. EURUSD, XAUUSD). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/getQuote?symbol=EURUSD" ``` Response: ```json { "symbol": "EURUSD", "bid": 1.15325, "ask": 1.15333, "time": "2026-06-11T08:55:56.728Z", "last": 0.0, "volume": 0 } ``` ### GET /mt5/{account_id}/PriceHistory OHLC bars for a symbol and timeframe: one candle per bar in the requested window. MT5 fetches missing history from the broker on demand, so wide ranges on small timeframes can take several seconds. An empty response is normal when the window predates the broker's retained history or covers a closed market. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `timeframe` (required): MT5 labels (M1, M5, M15, M30, H1, H4, D1, W1, MN1) or human forms (5min, 1h, 1d). - `from`: Inclusive lower bound (broker server time). ISO-8601 or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/PriceHistory?symbol=EURUSD&timeframe=H1&from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "time": "2026-06-11T08:00:00Z", "open": 1.15301, "high": 1.15348, "low": 1.15289, "close": 1.15330, "tickVolume": 1243, "realVolume": 0, "spread": 7 }] ``` ### GET /mt5/{account_id}/SymbolInfo Contract specification for a symbol: digits, point, spread, contract size, tick size/value, volume min/max/step, trade mode, swap rates, and base/quote/margin currencies. Call this before /OrderSend to validate volumes and round prices to the right precision. Parameters: - `symbol` (required): Symbol name as listed by /symbols. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/SymbolInfo?symbol=EURUSD" ``` Response: ```json { "symbol": "EURUSD", "description": "1 Lot= 100,000 EUR", "digits": 5, "point": 0.00001, "tickSize": 0.00001, "tickValue": 1.0, "contractSize": 100000.0, "volumeMin": 0.01, "volumeMax": 150000.0, "volumeStep": 0.01, "stopsLevel": 1, "freezeLevel": 0, "spread": 7, "tradeMode": "Full", "swapLong": -3.22, "swapShort": 1.1, "bid": 1.15324, "ask": 1.15331, "currencyBase": "EUR", "currencyProfit": "USD", "currencyMargin": "EUR" } ``` ### GET /mt5/{account_id}/ServerTimezone Broker server time and its offset from UTC. Timestamps across the API are labelled Z but run on broker server time; use utcOffsetSeconds to translate them to real UTC (utc = serverTime − utcOffsetSeconds). Most MetaTrader brokers run on EET (UTC+2, UTC+3 with DST). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt5/{account_id}/ServerTimezone ``` Response: ```json { "serverTime": "2026-06-11T08:55:57.000Z", "utcOffsetSeconds": 0 } ``` ## Related - [Trading](https://fxsocket.com/docs/mt5/trading.md) - [WebSocket Streams](https://fxsocket.com/docs/mt5/websocket.md) - [Account Data](https://fxsocket.com/docs/mt5/account-data.md) --- # MetaTrader 5 Trading API Source: https://fxsocket.com/docs/mt5/trading Place, modify, and close MetaTrader 5 orders over a REST API: market and pending orders, partial closes, plus margin and profit calculators for position sizing. Every order executes inside your own dedicated MT5 terminal, never a shared gateway. Base URL: `https://api.fxsocket.com/mt5/{account_id}` Order routes are executed inside your own terminal. A 200 response only means MT5 returned a result; always inspect success and retcode to confirm the broker accepted it. ### POST /mt5/{account_id}/OrderSend Submit a market or pending order. Market (Buy/Sell) needs symbol + volume; price is ignored. Pending (*Limit/*Stop) additionally needs price; StopLimit variants also need stopLimitPrice. Optional: slippage (default 10 points), stopLoss, takeProfit, expiration (absent → good-till-cancelled), comment, expertId (a.k.a. magic). Parameters: - `symbol` (required): Symbol to trade, e.g. EURUSD. - `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop, BuyStopLimit, SellStopLimit (case- and separator-insensitive). - `volume` (required): Volume in lots. - `price`: Required for pending orders; ignored for market orders. - `stopLimitPrice`: Required for *StopLimit operations. - `stopLoss / takeProfit`: Optional SL/TP prices. - `slippage`: Max slippage in points (default 10). - `expiration`: Date string; absent → good-till-cancelled. - `comment / expertId`: Order comment and magic number. Request body: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "stopLoss": 1.14800, "takeProfit": 1.16200, "comment": "my-strategy", "expertId": 123456 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt5/{account_id}/OrderSend \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"symbol":"EURUSD","operation":"Buy","volume":0.1,"stopLoss":1.148,"takeProfit":1.162,"comment":"my-strategy","expertId":123456}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 211438760, "order": 211438761, "volume": 0.1, "price": 1.15333, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### POST /mt5/{account_id}/OrderModify Modify an existing position or pending order. The ticket type decides what's modifiable: a position ticket accepts only stopLoss and takeProfit; a pending-order ticket also accepts price, stopLimitPrice, and expiration. Omit a field to keep its current value. Parameters: - `ticket` (required): Position or pending-order ticket. - `stopLoss / takeProfit`: New SL/TP; omit to keep current. - `price`: New price (pending orders only). - `stopLimitPrice`: New StopLimit price (*StopLimit pendings only). - `expiration`: New expiration (date string), pending orders only. Request body: ```json { "ticket": 211438761, "stopLoss": 1.15000, "takeProfit": 1.16500 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt5/{account_id}/OrderModify \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"ticket":211438761,"stopLoss":1.15,"takeProfit":1.165}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 0, "order": 211438761, "volume": 0.0, "price": 0.0, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### POST /mt5/{account_id}/OrderClose Close a position or delete a pending order: the action is inferred from the ticket type. For a position, supply volume for a partial close (must respect the symbol's volumeStep) or omit it for a full close. For a pending order, volume is ignored and the order is deleted. Parameters: - `ticket` (required): Position ticket (closes it) or pending-order ticket (deletes it). - `volume`: Partial close volume; omit or 0 = full close. - `slippage`: Max slippage in points. Request body: ```json { "ticket": 211438761, "volume": 0.05 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt5/{account_id}/OrderClose \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"ticket":211438761,"volume":0.05}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 211438770, "order": 211438771, "volume": 0.05, "price": 1.15325, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### GET /mt5/{account_id}/OrderCalcMargin Required margin for a hypothetical order. Asks MT5 to compute the broker-side margin needed to open the given volume at the given price, returned in the account currency. Does not place an order, purely a sizing/risk query. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop, BuyStopLimit, SellStopLimit. - `volume` (required): Volume in lots. - `price` (required): Hypothetical entry price. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/OrderCalcMargin?symbol=EURUSD&operation=Buy&volume=0.1&price=1.15333" ``` Response: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "price": 1.15333, "margin": 28.83, "currency": "USD" } ``` ### GET /mt5/{account_id}/OrderCalcProfit Projected P&L for a hypothetical open → close move, returned in the account currency. Does not place an order, useful for position sizing and UI. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `operation` (required): Buy or Sell (pending variants accepted, only the direction is used). - `volume` (required): Volume in lots. - `priceOpen` (required): Hypothetical open price. - `priceClose` (required): Hypothetical close price. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt5/{account_id}/OrderCalcProfit?symbol=EURUSD&operation=Buy&volume=0.1&priceOpen=1.15333&priceClose=1.16333" ``` Response: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "priceOpen": 1.15333, "priceClose": 1.16333, "profit": 100.0, "currency": "USD" } ``` ## Related - [Account Data](https://fxsocket.com/docs/mt5/account-data.md) - [Market Data](https://fxsocket.com/docs/mt5/market-data.md) - [Errors & Rate Limits](https://fxsocket.com/docs/mt5/errors.md) --- # MetaTrader 5 WebSocket API Source: https://fxsocket.com/docs/mt5/websocket Stream live MetaTrader 5 data over a single WebSocket per account: ticks, OHLC bar closes, account updates, open positions, trade events, and terminal status. Subscribe and unsubscribe with simple JSON control frames, no polling. ### WS wss://api.fxsocket.com/mt5/{account_id}/ws?api_key=fxs_live_... One streaming socket per account. Authentication is via the api_key query parameter, the only method available on WebSocket connections. Send JSON control frames to subscribe and unsubscribe; on subscribe the server first sends one current snapshot (account / positions / prices) before streaming deltas. Non-browser clients: the upgrade requires HTTP/1.1. Six topics are available: - `prices`: Per-symbol ticks (requires symbol). - `bars`: OHLC bar closes per symbol + timeframe (requires symbol and timeframe). - `account`: Account snapshot, then changes. - `positions`: Open positions snapshot, then changes. - `trades`: Trade events as they happen. - `terminal`: Terminal status, roughly once per second. Client → server frames: ``` {"action": "subscribe", "topic": "prices", "symbol": "EURUSD"} {"action": "subscribe", "topic": "bars", "symbol": "EURUSD", "timeframe": "M5"} {"action": "subscribe", "topic": "account"} {"action": "unsubscribe", "topic": "prices", "symbol": "EURUSD"} ``` ### WS server → client messages Every server message is a JSON object with a type. Data messages mirror the REST shapes; control replies confirm your frames. Slow consumers get dropped messages plus a warning message rather than a stalled socket. Server → client messages: ``` {"type": "tick", "symbol": "EURUSD", "data": {"bid": 1.15325, "ask": 1.15333, "last": 0.0, "volume": 0, "time": "2026-06-11T08:55:56.728Z"}} {"type": "bar", "symbol": "EURUSD", "timeframe": "M5", "data": {"open": 1.15301, "high": 1.15348, "low": 1.15289, "close": 1.15330}} {"type": "account", "data": { ... }} {"type": "positions", "data": [ ... ]} {"type": "trade", "data": { ... }} {"type": "terminal", "data": {"connected": true, "tradeAllowed": true, "serverTime": "2026-06-11T08:55:57.000Z"}} {"type": "subscribed" | "unsubscribed" | "error" | "warning", ...} ``` ### GET /ws-tester A built-in browser tester is served per account at https://api.fxsocket.com/mt5/{account_id}/ws-tester?api_key=fxs_live_... (handy for poking at the stream before writing code). The page is API-key gated, and since browsers can't attach headers the key must ride in the URL (it will appear in your browser history). Open yours from the Request Builder on the overview page. ## Related - [Market Data](https://fxsocket.com/docs/mt5/market-data.md) - [Account Data](https://fxsocket.com/docs/mt5/account-data.md) - [Trading](https://fxsocket.com/docs/mt5/trading.md) --- # MetaTrader 5 API Errors & Rate Limits Source: https://fxsocket.com/docs/mt5/errors Every error from the MetaTrader 5 API is machine-readable. Auth failures return a fixed code, and everything else (timeouts, validation, broker or MQL rejections) comes back in a uniform envelope you can branch on. ## Errors A wrong or missing API key returns HTTP 401 with `MRPC_UNAUTHORIZED` (see [Authentication](https://fxsocket.com/docs/mt5/authentication.md)). An unknown account ID or path returns a plain 404 from the edge. Everything else (timeouts, validation failures, broker/MQL rejections) comes back in a uniform envelope with an `error` code, a `message`, and a `command_id` for log correlation: ```json { "error": "MRPC_TIMEOUT", "message": "MarketInfo.PriceHistory timed out", "command_id": 19 } ``` 5xx responses come in two flavors. A `500` or `504` with the envelope above means the terminal processed your request but the underlying operation failed or timed out, for example `{"error": "MRPC", "message": "CopyRates failed"}` when requesting history for a symbol your broker doesn't list (check `/symbols` for the exact spelling, suffixes included). Envelope-less 5xx responses mean the terminal itself is down or restarting, for example during the brief restart after an API-key rotation. Trading routes can briefly return 503 right after a terminal start, before the trade engine has registered. ## Rate Limits Terminal requests are served by your own dedicated terminal, so heavy polling only slows down your own account, nobody else's. Platform routes under `/v1` are rate limited per API key: if you exceed a limit you get a `429` with a `Retry-After` header, so wait that long and retry. For live prices, positions, or account changes, prefer the [WebSocket streams](https://fxsocket.com/docs/mt5/websocket.md) over polling: you get pushed updates without burning round-trips. ## Related - [Authentication](https://fxsocket.com/docs/mt5/authentication.md) - [Trading](https://fxsocket.com/docs/mt5/trading.md) - [WebSocket Streams](https://fxsocket.com/docs/mt5/websocket.md) --- # MetaTrader 4 REST & WebSocket API Source: https://fxsocket.com/docs/mt4 FxSocket exposes each connected MetaTrader 4 account through a REST API and a WebSocket stream. Every account gets its own dedicated MT4 terminal in our cloud. Requests to your account hit your own terminal, nobody shares it. All endpoints return JSON. Per-account base URL: `https://api.fxsocket.com/mt4/{account_id}` `{account_id}` is the UUID of your connected MT4 account. Copy it from the Accounts page (https://app.fxsocket.com/dashboard/accounts) or read it from GET https://api.fxsocket.com/v1/accounts. Your API key lives on the API Key page (https://app.fxsocket.com/dashboard/api-key). You can link, list, and remove accounts from the dashboard, or programmatically through the account-management API at `https://api.fxsocket.com/v1`. See [Managing Accounts](https://fxsocket.com/docs/mt4/accounts.md). ## Explore the MT4 API - [Authentication](https://fxsocket.com/docs/mt4/authentication.md): API keys: header or query parameter. - [Managing Accounts](https://fxsocket.com/docs/mt4/accounts.md): Link, list, and remove accounts via /v1. - [Account Data](https://fxsocket.com/docs/mt4/account-data.md): Balances, positions, history, and connection status. - [Market Data](https://fxsocket.com/docs/mt4/market-data.md): Symbols, quotes, price history, and contract specs. - [Trading](https://fxsocket.com/docs/mt4/trading.md): Place, modify, and close orders. - [WebSocket Streams](https://fxsocket.com/docs/mt4/websocket.md): Live ticks, bars, positions, and trades. - [Errors & Rate Limits](https://fxsocket.com/docs/mt4/errors.md): Error envelope, status codes, and rate limits. ## SDKs & Generated Clients The official FxSocket SDKs wrap this API (account management, trading, market data, and live WebSocket streams) with typed models for MT4 and MT5: - Python: `pip install fxsocket`, sync and async clients. PyPI: https://pypi.org/project/fxsocket/ · GitHub: https://github.com/fxsocket-com/FxSocket-Python-SDK - Node.js / TypeScript: `npm install @fxsocket/sdk`, ESM and CommonJS. npm: https://www.npmjs.com/package/@fxsocket/sdk · GitHub: https://github.com/fxsocket-com/FxSocket-Node-SDK Using another language? The API is plain HTTP and JSON, and every account serves its own live OpenAPI 3 spec, so you can generate a typed client for any language instead: - Swagger UI: `https://api.fxsocket.com/mt4/{account_id}/swagger-ui/`: browsable, per-account interactive docs (keep the trailing slash). No API key needed. - Raw spec: `https://api.fxsocket.com/mt4/{account_id}/api-doc/openapi.json`: point any OpenAPI generator (openapi-generator, openapi-typescript, oapi-codegen, ...) at this URL. These two routes (plus `/`) are the only ones served without an API key. --- # MetaTrader 4 API Authentication Source: https://fxsocket.com/docs/mt4/authentication Every FxSocket API request is authenticated with a per-user API key, passed as an X-API-Key header, or as an api_key query parameter for clients (like WebSocket) that can't set headers. There is no OAuth dance or Bearer scheme to manage, and your key only works against your own MetaTrader 4 accounts. ### Header X-API-Key: fxs_live_... Every request needs your fxsocket API key, copy it from the dashboard's API Key page. Keys are per-user and only work on your own accounts: authentication is enforced by your own dedicated terminal, and a valid key used against someone else's account_id still gets a 401. 401 response: ```json { "error": "MRPC_UNAUTHORIZED", "message": "missing or invalid API key (X-API-Key header or api_key query parameter)" } ``` ### Query ?api_key=fxs_live_... Alternative to the header, and the only method WebSocket clients can use. The key is the same in both cases. There is no Bearer / Authorization scheme. Rotating your key from the dashboard propagates to your terminals within about 5 minutes. The terminal restarts briefly when the new key lands, so a short window of 5xx responses right after a rotation is normal. ## Related - [Managing Accounts](https://fxsocket.com/docs/mt4/accounts.md) - [Account Data](https://fxsocket.com/docs/mt4/account-data.md) - [Errors & Rate Limits](https://fxsocket.com/docs/mt4/errors.md) --- # MT4 Account Management API Source: https://fxsocket.com/docs/mt4/accounts Link, list, and remove MetaTrader 4 accounts programmatically with the account-management API. Linking an account provisions its own dedicated MT4 terminal in our cloud and returns the account_id you'll use across every per-account REST and WebSocket route. Base URL: `https://api.fxsocket.com/v1` Link, list, and remove MT4 accounts programmatically. These endpoints live under a different base URL (https://api.fxsocket.com/v1) and use the same X-API-Key authentication. Linking an account provisions its own dedicated terminal; once its status reads "connected" you can drive it through the per-account REST and WebSocket API documented below. ### GET /v1/accounts List every MT4 account linked to your API key. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts ``` Response: ```json [{ "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt4", "server": "VTMarkets-Demo", "login": 1234567, "status": "connected", "error": "", "created_at": "2026-06-13T22:52:23Z" }] ``` ### POST /v1/accounts Link a new MT4 account and provision its terminal. The response comes back with status "connecting". Poll GET /v1/accounts/{account_id} until it reads "connected" (usually 1–3 minutes). Returns 402 if you're at your plan's account limit, 409 if the account is already linked, or 400 if the broker rejects the login. MT4 only. Parameters: - `server` (required): Broker server name, exactly as MT4 shows it (e.g. VTMarkets-Demo). - `login` (required): MT4 account login number. - `password` (required): Account password (investor or master). Stored encrypted; never returned. - `nickname`: Optional label shown in the dashboard. Request body: ```json { "server": "VTMarkets-Demo", "login": 1234567, "password": "your-account-password", "nickname": "my demo" } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/v1/accounts \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"server":"VTMarkets-Demo","login":1234567,"password":"your-account-password","nickname":"my demo"}' ``` 201 response: ```json { "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt4", "server": "VTMarkets-Demo", "login": 1234567, "status": "connecting", "error": "", "created_at": "2026-06-13T22:52:23Z" } ``` ### GET /v1/accounts/{account_id} Fetch a single account by id, use it to poll status after linking, until it turns "connected". Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts/{account_id} ``` Response: ```json { "id": "b5236acf-c39b-4e8b-be64-a96afb7e6086", "nickname": "my demo", "platform": "mt4", "server": "VTMarkets-Demo", "login": 1234567, "status": "connected", "error": "", "created_at": "2026-06-13T22:52:23Z" } ``` ### DELETE /v1/accounts/{account_id} Unlink an account: disconnects it, tears down its dedicated terminal, and removes it, freeing the account slot on your plan. Returns 204 No Content with an empty body. Example request: ```bash curl -X DELETE \ -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/v1/accounts/{account_id} ``` Response: ``` 204 No Content ``` status is the account's overall health: "connecting" while its terminal is still starting up (typically 1–3 minutes after linking), "connected" once it's logged in and serving data, "error" if provisioning or the broker login failed (see the error field), and "disconnected" otherwise. The id returned here is the {account_id} used in every per-account route below. ## Related - [Authentication](https://fxsocket.com/docs/mt4/authentication.md) - [Account Data](https://fxsocket.com/docs/mt4/account-data.md) - [Trading](https://fxsocket.com/docs/mt4/trading.md) --- # MetaTrader 4 Account Data & Status API Source: https://fxsocket.com/docs/mt4/account-data Read live and static state for a connected MetaTrader 4 account: balance and equity, the static account configuration, open positions and pending orders, trade and position history, and a single connection-health endpoint to confirm the account is logged in and trading-ready. Base URL: `https://api.fxsocket.com/mt4/{account_id}` ### GET /mt4/{account_id}/AccountSummary Snapshot of the connected trading account: balance, credit, floating profit, equity, margin, free margin, margin level, leverage, account currency, and account type. Reflects broker-side state at call time, no caching. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/AccountSummary ``` Response: ```json { "balance": 9686.15, "credit": 0.0, "profit": 0.0, "equity": 9686.15, "margin": 0.0, "freeMargin": 9686.15, "marginLevel": 0.0, "leverage": 400, "currency": "USD", "type": "Demo" } ``` ### GET /mt4/{account_id}/AccountInfo Static identity and configuration of the account: the who-and-how that rarely changes, as opposed to the live financials in /AccountSummary. Includes the account holder name, login, broker company and server, currency, leverage, account type, margin mode (Netting / Hedging / Exchange, needed to know whether an opposite order nets a position or opens a new one), stop-out configuration, and trade permissions. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/AccountInfo ``` Response: ```json { "name": "Lars Joeressen", "login": 2100152454, "server": "TegasFX-Demo", "company": "TegasFX Ltd", "currency": "USD", "currencyDigits": 2, "leverage": 200, "type": "Demo", "marginMode": "Hedging", "marginSoMode": "Percent", "marginCallLevel": 100.0, "stopOutLevel": 70.0, "tradeAllowed": true, "tradeExpert": true, "limitOrders": 200, "fifoClose": false } ``` ### GET /mt4/{account_id}/OpenedOrders All open positions and active pending orders: one row per position (already-filled trade) and one per pending order (limit / stop / stop-limit). kind discriminates the two; pending orders show their trigger price in openPrice and carry zero swap/profit. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/OpenedOrders ``` Response: ```json [{ "ticket": 211438758, "symbol": "USDJPY", "type": "Sell", "kind": "position", "lots": 0.1, "openPrice": 160.505, "currentPrice": 160.547, "stopLoss": 160.576, "takeProfit": 160.458, "swap": 0.0, "profit": -2.62, "magic": 0, "comment": "", "openTime": "2026-06-11T11:02:04.000Z" }, { "ticket": 211583734, "symbol": "GBPUSD", "type": "BuyStop", "kind": "pending", "lots": 0.01, "openPrice": 1.34958, "currentPrice": 1.33683, "stopLoss": 1.34611, "takeProfit": 1.35275, "swap": 0.0, "profit": 0.0, "magic": 0, "comment": "", "openTime": "2026-06-10T09:30:00.000Z" }] ``` ### GET /mt4/{account_id}/OrderHistory Closed deals in a time range. Returns DEAL entries (executions), not ORDER entries; pending orders that never filled don't appear here. Omit both bounds to fetch all-time history. Parameters: - `from`: Inclusive lower bound (broker server time). ISO-8601 (2026-01-01T00:00:00Z) or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/OrderHistory?from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "ticket": 211438992, "order": 211438991, "symbol": "EURUSD", "type": "Sell", "entry": "Out", "volume": 0.1, "price": 1.15410, "commission": -0.40, "swap": 0.0, "profit": 12.00, "magic": 0, "comment": "", "time": "2026-06-10T15:42:11Z" }] ``` ### GET /mt4/{account_id}/PositionHistory Closed positions in a time range: one row per round-trip trade (open → close), reconstructed from the underlying deals with volume-weighted open/close prices. Use this when you want net results per position; use /OrderHistory when you need the raw deal log. Omit both bounds to fetch all-time history. Parameters: - `from`: Inclusive lower bound (broker server time). ISO-8601 (2026-01-01T00:00:00Z) or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/PositionHistory?from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "positionId": 211438758, "symbol": "EURUSD", "type": "Buy", "volume": 0.1, "openTime": "2026-06-10T09:12:04.000Z", "openPrice": 1.15201, "closeTime": "2026-06-10T15:42:11.000Z", "closePrice": 1.15410, "profit": 20.90, "swap": 0.0, "commission": -0.80, "netProfit": 20.10, "magic": 0, "comment": "" }] ``` ### GET /mt4/{account_id}/status Full connection health of the terminal, in one call: is the terminal alive, is it connected to the broker, and is the account logged in? Use this to confirm an account is live and trading-ready before sending orders. Always returns HTTP 200. Read the body to see the actual state. The top-level status is ready (everything healthy and the account logged in), starting (still booting / logging in), degraded (e.g. broker disconnected), or down. For lightweight probes there are also two unauthenticated routes that signal via HTTP status code: GET /healthz (200 once fully ready, 503 otherwise) and GET /livez (200 while the terminal is alive, regardless of broker connection). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/status ``` Response: ```json { "status": "ready", "terminal": { "alive": true, "build": 5180, "pingMs": 42 }, "broker": { "connected": true, "server": "TegasFX-Demo" }, "account": { "loggedIn": true, "login": 2100152454, "currency": "USD", "type": "Demo", "tradeAllowed": true }, "bridge": { "version": "0.2.0", "tradeEaReady": true, "symbolsSynced": true }, "serverTime": "2026-06-11T08:55:57.000Z" } ``` ## Related - [Trading](https://fxsocket.com/docs/mt4/trading.md) - [Market Data](https://fxsocket.com/docs/mt4/market-data.md) - [WebSocket Streams](https://fxsocket.com/docs/mt4/websocket.md) --- # MetaTrader 4 Market Data API Source: https://fxsocket.com/docs/mt4/market-data Pull MetaTrader 4 market data over REST: the broker's symbol list, latest quotes, full contract specifications, OHLC price history for any timeframe, and broker server time. For a continuous tick feed, use the WebSocket prices stream instead of polling. Base URL: `https://api.fxsocket.com/mt4/{account_id}` ### GET /mt4/{account_id}/symbols Names of all symbols available in Market Watch. Use the returned names verbatim with /getQuote, /SymbolInfo, /PriceHistory, and /OrderSend, since many brokers suffix their symbols (EURUSD.sd, XAUUSD.r), so discover the exact spelling here instead of assuming plain names. A symbol not in Market Watch can't stream ticks until it's added, but a getQuote call enables it on demand. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/symbols ``` Response: ```json ["EURUSD.sd", "GBPUSD.sd", "USDJPY.sd", "XAUUSD.sd", "..."] ``` ### GET /mt4/{account_id}/getQuote Latest tick for a symbol: the most recent bid, ask, last, volume, and broker server time. If the symbol isn't yet in Market Watch it's enabled on demand, which may add a small delay on the first call. For continuous ticks use the WebSocket prices topic instead. Parameters: - `symbol` (required): Symbol name as listed by /symbols (e.g. EURUSD, XAUUSD). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/getQuote?symbol=EURUSD" ``` Response: ```json { "symbol": "EURUSD", "bid": 1.15325, "ask": 1.15333, "time": "2026-06-11T08:55:56.728Z", "last": 0.0, "volume": 0 } ``` ### GET /mt4/{account_id}/PriceHistory OHLC bars for a symbol and timeframe: one candle per bar in the requested window. MT4 fetches missing history from the broker on demand, so wide ranges on small timeframes can take several seconds. An empty response is normal when the window predates the broker's retained history or covers a closed market. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `timeframe` (required): MT4 labels (M1, M5, M15, M30, H1, H4, D1, W1, MN1) or human forms (5min, 1h, 1d). - `from`: Inclusive lower bound (broker server time). ISO-8601 or YYYY-MM-DD. Absent → epoch. - `to`: Inclusive upper bound, same formats. Absent → now. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/PriceHistory?symbol=EURUSD&timeframe=H1&from=2026-01-01&to=2026-12-31" ``` Response: ```json [{ "time": "2026-06-11T08:00:00Z", "open": 1.15301, "high": 1.15348, "low": 1.15289, "close": 1.15330, "tickVolume": 1243, "realVolume": 0, "spread": 7 }] ``` ### GET /mt4/{account_id}/SymbolInfo Contract specification for a symbol: digits, point, spread, contract size, tick size/value, volume min/max/step, trade mode, swap rates, and base/quote/margin currencies. Call this before /OrderSend to validate volumes and round prices to the right precision. Parameters: - `symbol` (required): Symbol name as listed by /symbols. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/SymbolInfo?symbol=EURUSD" ``` Response: ```json { "symbol": "EURUSD", "description": "1 Lot= 100,000 EUR", "digits": 5, "point": 0.00001, "tickSize": 0.00001, "tickValue": 1.0, "contractSize": 100000.0, "volumeMin": 0.01, "volumeMax": 150000.0, "volumeStep": 0.01, "stopsLevel": 1, "freezeLevel": 0, "spread": 7, "tradeMode": "Full", "swapLong": -3.22, "swapShort": 1.1, "bid": 1.15324, "ask": 1.15331, "currencyBase": "EUR", "currencyProfit": "USD", "currencyMargin": "EUR" } ``` ### GET /mt4/{account_id}/ServerTimezone Broker server time and its offset from UTC. Timestamps across the API are labelled Z but run on broker server time. Use utcOffsetSeconds to translate them to real UTC (utc = serverTime − utcOffsetSeconds). Most MetaTrader brokers run on EET (UTC+2, UTC+3 with DST). Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ https://api.fxsocket.com/mt4/{account_id}/ServerTimezone ``` Response: ```json { "serverTime": "2026-06-11T08:55:57.000Z", "utcOffsetSeconds": 0 } ``` ## Related - [Trading](https://fxsocket.com/docs/mt4/trading.md) - [WebSocket Streams](https://fxsocket.com/docs/mt4/websocket.md) - [Account Data](https://fxsocket.com/docs/mt4/account-data.md) --- # MetaTrader 4 Trading API Source: https://fxsocket.com/docs/mt4/trading Place, modify, and close MetaTrader 4 orders over a REST API: market and pending orders, partial closes, plus margin and profit calculators for position sizing. Every order executes inside your own dedicated MT4 terminal, never a shared gateway. Base URL: `https://api.fxsocket.com/mt4/{account_id}` Order routes are executed inside your own terminal. A 200 response only means MT4 returned a result. Always inspect success and retcode to confirm the broker accepted it. ### POST /mt4/{account_id}/OrderSend Submit a market or pending order. Market (Buy/Sell) needs symbol + volume, price is ignored. Pending (*Limit/*Stop) additionally needs price; StopLimit variants also need stopLimitPrice. Optional: slippage (default 10 points), stopLoss, takeProfit, expiration (absent → good-till-cancelled), comment, expertId (a.k.a. magic). Parameters: - `symbol` (required): Symbol to trade, e.g. EURUSD. - `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop, BuyStopLimit, SellStopLimit (case- and separator-insensitive). - `volume` (required): Volume in lots. - `price`: Required for pending orders; ignored for market orders. - `stopLimitPrice`: Required for *StopLimit operations. - `stopLoss / takeProfit`: Optional SL/TP prices. - `slippage`: Max slippage in points (default 10). - `expiration`: Date string; absent → good-till-cancelled. - `comment / expertId`: Order comment and magic number. Request body: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "stopLoss": 1.14800, "takeProfit": 1.16200, "comment": "my-strategy", "expertId": 123456 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderSend \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"symbol":"EURUSD","operation":"Buy","volume":0.1,"stopLoss":1.148,"takeProfit":1.162,"comment":"my-strategy","expertId":123456}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 211438760, "order": 211438761, "volume": 0.1, "price": 1.15333, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### POST /mt4/{account_id}/OrderModify Modify an existing position or pending order. The ticket type decides what's modifiable: a position ticket accepts only stopLoss and takeProfit; a pending-order ticket also accepts price, stopLimitPrice, and expiration. Omit a field to keep its current value. Parameters: - `ticket` (required): Position or pending-order ticket. - `stopLoss / takeProfit`: New SL/TP, omit to keep current. - `price`: New price, pending orders only. - `stopLimitPrice`: New StopLimit price, *StopLimit pendings only. - `expiration`: New expiration (date string), pending orders only. Request body: ```json { "ticket": 211438761, "stopLoss": 1.15000, "takeProfit": 1.16500 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderModify \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"ticket":211438761,"stopLoss":1.15,"takeProfit":1.165}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 0, "order": 211438761, "volume": 0.0, "price": 0.0, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### POST /mt4/{account_id}/OrderClose Close a position or delete a pending order: the action is inferred from the ticket type. For a position, supply volume for a partial close (must respect the symbol's volumeStep) or omit it for a full close. For a pending order, volume is ignored and the order is deleted. Parameters: - `ticket` (required): Position ticket (closes it) or pending-order ticket (deletes it). - `volume`: Partial close volume; omit or 0 = full close. - `slippage`: Max slippage in points. Request body: ```json { "ticket": 211438761, "volume": 0.05 } ``` Example request: ```bash curl -X POST https://api.fxsocket.com/mt4/{account_id}/OrderClose \ -H "X-API-Key: fxs_live_..." \ -H "Content-Type: application/json" \ -d '{"ticket":211438761,"volume":0.05}' ``` Response: ```json { "success": true, "retcode": 10009, "retcodeDescription": "Request completed", "deal": 211438770, "order": 211438771, "volume": 0.05, "price": 1.15325, "bid": 1.15325, "ask": 1.15333, "comment": "" } ``` ### GET /mt4/{account_id}/OrderCalcMargin Required margin for a hypothetical order. Asks MT4 to compute the broker-side margin needed to open the given volume at the given price, returned in the account currency. Does not place an order, purely a sizing/risk query. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `operation` (required): Buy, Sell, BuyLimit, SellLimit, BuyStop, SellStop, BuyStopLimit, SellStopLimit. - `volume` (required): Volume in lots. - `price` (required): Hypothetical entry price. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/OrderCalcMargin?symbol=EURUSD&operation=Buy&volume=0.1&price=1.15333" ``` Response: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "price": 1.15333, "margin": 28.83, "currency": "USD" } ``` ### GET /mt4/{account_id}/OrderCalcProfit Projected P&L for a hypothetical open → close move, returned in the account currency. Does not place an order, useful for position sizing and UI. Parameters: - `symbol` (required): Symbol name as listed by /symbols. - `operation` (required): Buy or Sell (pending variants accepted: only the direction is used). - `volume` (required): Volume in lots. - `priceOpen` (required): Hypothetical open price. - `priceClose` (required): Hypothetical close price. Example request: ```bash curl -H "X-API-Key: fxs_live_..." \ "https://api.fxsocket.com/mt4/{account_id}/OrderCalcProfit?symbol=EURUSD&operation=Buy&volume=0.1&priceOpen=1.15333&priceClose=1.16333" ``` Response: ```json { "symbol": "EURUSD", "operation": "Buy", "volume": 0.1, "priceOpen": 1.15333, "priceClose": 1.16333, "profit": 100.0, "currency": "USD" } ``` ## Related - [Account Data](https://fxsocket.com/docs/mt4/account-data.md) - [Market Data](https://fxsocket.com/docs/mt4/market-data.md) - [Errors & Rate Limits](https://fxsocket.com/docs/mt4/errors.md) --- # MetaTrader 4 WebSocket API Source: https://fxsocket.com/docs/mt4/websocket Stream live MetaTrader 4 data over a single WebSocket per account: ticks, OHLC bar closes, account updates, open positions, trade events, and terminal status. Subscribe and unsubscribe with simple JSON control frames, no polling. ### WS wss://api.fxsocket.com/mt4/{account_id}/ws?api_key=fxs_live_... One streaming socket per account. Authentication is via the api_key query parameter, the only method available on WebSocket connections. Send JSON control frames to subscribe and unsubscribe; on subscribe the server first sends one current snapshot (account / positions / prices) before streaming deltas. Non-browser clients: the upgrade requires HTTP/1.1. Six topics are available: - `prices`: Per-symbol ticks (requires symbol). - `bars`: OHLC bar closes per symbol + timeframe (requires symbol and timeframe). - `account`: Account snapshot, then changes. - `positions`: Open positions snapshot, then changes. - `trades`: Trade events as they happen. - `terminal`: Terminal status, roughly once per second. Client → server frames: ``` {"action": "subscribe", "topic": "prices", "symbol": "EURUSD"} {"action": "subscribe", "topic": "bars", "symbol": "EURUSD", "timeframe": "M5"} {"action": "subscribe", "topic": "account"} {"action": "unsubscribe", "topic": "prices", "symbol": "EURUSD"} ``` ### WS server → client messages Every server message is a JSON object with a type. Data messages mirror the REST shapes; control replies confirm your frames. Slow consumers get dropped messages plus a warning message rather than a stalled socket. Server → client messages: ``` {"type": "tick", "symbol": "EURUSD", "data": {"bid": 1.15325, "ask": 1.15333, "last": 0.0, "volume": 0, "time": "2026-06-11T08:55:56.728Z"}} {"type": "bar", "symbol": "EURUSD", "timeframe": "M5", "data": {"open": 1.15301, "high": 1.15348, "low": 1.15289, "close": 1.15330}} {"type": "account", "data": { ... }} {"type": "positions", "data": [ ... ]} {"type": "trade", "data": { ... }} {"type": "terminal", "data": {"connected": true, "tradeAllowed": true, "serverTime": "2026-06-11T08:55:57.000Z"}} {"type": "subscribed" | "unsubscribed" | "error" | "warning", ...} ``` ### GET /ws-tester A built-in browser tester is served per account at https://api.fxsocket.com/mt4/{account_id}/ws-tester?api_key=fxs_live_... (handy for poking at the stream before writing code). The page is API-key gated, and since browsers can't attach headers the key must ride in the URL (it will appear in your browser history). Open yours from the Request Builder on the overview page. ## Related - [Market Data](https://fxsocket.com/docs/mt4/market-data.md) - [Account Data](https://fxsocket.com/docs/mt4/account-data.md) - [Trading](https://fxsocket.com/docs/mt4/trading.md) --- # MetaTrader 4 API Errors & Rate Limits Source: https://fxsocket.com/docs/mt4/errors Every error from the MetaTrader 4 API is machine-readable. Auth failures return a fixed code, and everything else (timeouts, validation, broker or MQL rejections) comes back in a uniform envelope you can branch on. ## Errors A wrong or missing API key returns HTTP 401 with `MRPC_UNAUTHORIZED` (see [Authentication](https://fxsocket.com/docs/mt4/authentication.md)). An unknown account ID or path returns a plain 404 from the edge. Everything else (timeouts, validation failures, broker/MQL rejections) comes back in a uniform envelope with an `error` code, a `message`, and a `command_id` for log correlation: ```json { "error": "MRPC_TIMEOUT", "message": "MarketInfo.PriceHistory timed out", "command_id": 19 } ``` 5xx responses come in two flavors. A `500` or `504` with the envelope above means the terminal processed your request but the underlying operation failed or timed out, for example `{"error": "MRPC", "message": "CopyRates failed"}` when requesting history for a symbol your broker doesn't list (check `/symbols` for the exact spelling, suffixes included). Envelope-less 5xx responses mean the terminal itself is down or restarting, for example during the brief restart after an API-key rotation. Trading routes can briefly return 503 right after a terminal start, before the trade engine has registered. ## Rate Limits Terminal requests are served by your own dedicated terminal, so heavy polling only slows down your own account, nobody else's. Platform routes under `/v1` are rate limited per API key: if you exceed a limit you get a `429` with a `Retry-After` header, so wait that long and retry. For live prices, positions, or account changes, prefer the [WebSocket streams](https://fxsocket.com/docs/mt4/websocket.md) over polling: you get pushed updates without burning round-trips. ## Related - [Authentication](https://fxsocket.com/docs/mt4/authentication.md) - [Trading](https://fxsocket.com/docs/mt4/trading.md) - [WebSocket Streams](https://fxsocket.com/docs/mt4/websocket.md) --- # The /v1 platform API Source: https://fxsocket.com/docs/api Every connected trading account has its own terminal, with its own REST and WebSocket API. The platform API is the layer above that: the endpoints that are about your whole account rather than one terminal. Trade across many accounts in one call, and fund them from a prepaid balance. It spans MetaTrader 4 and MetaTrader 5 alike, so the same batch can carry both. Base URL: `https://api.fxsocket.com/v1` Same authentication as the rest of the API: an `X-API-Key` header carrying the key from your API Key page (https://app.fxsocket.com/dashboard/api-key). Paths have no trailing slash and are not rewritten, so `/v1/orders` is exact. Anything that moves money or places a trade needs the full `fxs_live_` key; a read-only `fxs_ro_` key can call every GET here and gets a `403` on the rest. ## Explore the platform API - [Multi-account execution](https://fxsocket.com/docs/api/batch-orders.md): One order to many accounts, and selector-based closes across them. - [Balance & top-ups](https://fxsocket.com/docs/api/wallet.md): Prepaid balance, crypto top-ups, seats and upcoming charges. ## Per-account routes live elsewhere Linking accounts, reading balances and positions, quotes and price history, single-account order execution and the live WebSocket streams are all documented per terminal: [MetaTrader 5](https://fxsocket.com/docs/mt5.md) and [MetaTrader 4](https://fxsocket.com/docs/mt4.md). The `account_id` those pages talk about is the same one you pass to the batch endpoints here. ## OpenAPI and SDKs The whole `/v1` surface, including everything on these pages, is published as OpenAPI 3 and browsable without a key: - Swagger UI: https://api.fxsocket.com/v1/docs - Raw spec: https://api.fxsocket.com/v1/schema (point any OpenAPI generator at this URL) The official SDKs wrap it with typed models: `pip install fxsocket` (https://pypi.org/project/fxsocket/) and `npm install @fxsocket/sdk` (https://www.npmjs.com/package/@fxsocket/sdk). For AI agents there is a read-only [MCP server](https://fxsocket.com/docs/mcp.md) over the same accounts and keys. --- # Multi-account execution Source: https://fxsocket.com/docs/api/batch-orders Copy trading, prop-desk fan-out and portfolio hedging all come down to one thing: doing the same trade on many accounts without writing a loop that half-fails. These two endpoints take a batch, dispatch every account concurrently to its own terminal, and answer with a per-account result. MT4 and MT5 can sit in the same batch. Base URL: `https://api.fxsocket.com/v1` Send one order to many accounts, or close across many accounts by selector, in a single call. Both endpoints fan out concurrently to each account's own terminal, work across MT4 and MT5 in the same batch, and need the full API key: a read-only key gets a 403. They are rate limited separately from the rest of the API at 60 requests/min. ### POST /v1/orders Fan a single request out to several of your accounts at once, each leg with its own symbol, side, lot size and stops. Every leg inherits defaults and may override any of it, including with a falsy value, so slippage: 0 means zero rather than fall back. At most 20 legs per batch. Fields are snake_case; an unknown field is a 400 rather than a silent drop, because a quietly ignored stopLoss would place a naked position. Parameters: - `defaults`: Values every leg inherits: symbol, operation, volume, price, slippage, stop_loss, take_profit, stop_limit_price, expiration, comment, expert_id. - `orders` (required): One entry per order. account_id is required; every other field either comes from defaults or is set here. - `orders[].account_id` (required): One of your accounts, as returned by GET /v1/accounts. The same account may appear more than once. - `orders[].operation`: buy, sell, buyLimit, sellLimit, buyStop, sellStop, buyStopLimit or sellStopLimit (case-insensitive). - `orders[].volume`: Lots. Must be greater than 0. - `Idempotency-Key`: Header, up to 128 characters. Replaying the identical body with the same key returns the original response and sends nothing. Keys live 15 minutes. Request body: ```json { "defaults": { "operation": "buy", "symbol": "EURUSD", "slippage": 20 }, "orders": [ { "account_id": "6fcb1e23-8ea8-4674-aa62-3d48fd08f309", "volume": 0.10 }, { "account_id": "a91b0d47-2c31-4f8a-9d76-1e5b0c3a7f42", "volume": 0.25, "symbol": "EURUSD.sd" }, { "account_id": "c73d55e2-90b4-4a17-8f3c-6d2e9a1b4c85", "volume": 0.01, "symbol": "XAUUSD", "operation": "sell", "stop_loss": 2410.0 } ] } ``` 200 response: ```json { "batch_id": "b_01J8Z4M7Q2K3V9", "idempotent_replay": false, "summary": { "requested": 3, "filled": 1, "failed": 2, "unknown": 0 }, "results": [ { "account_id": "6fcb1e23-8ea8-4674-aa62-3d48fd08f309", "platform": "mt5", "symbol": "EURUSD", "operation": "buy", "volume": 0.10, "status": "filled", "order": 1234567, "deal": 987654, "price": 1.08423, "bid": 1.08421, "ask": 1.08423, "retcode": 10009, "retcode_description": "TRADE_RETCODE_DONE", "message": "", "latency_ms": 812 }, { "account_id": "a91b0d47-2c31-4f8a-9d76-1e5b0c3a7f42", "platform": "mt5", "symbol": "EURUSD.sd", "operation": "buy", "volume": 0.25, "status": "rejected", "order": 0, "deal": 0, "retcode": 10019, "retcode_description": "TRADE_RETCODE_NO_MONEY", "message": "not enough money", "latency_ms": 640 }, { "account_id": "c73d55e2-90b4-4a17-8f3c-6d2e9a1b4c85", "platform": "mt4", "symbol": "XAUUSD", "operation": "sell", "volume": 0.01, "status": "unavailable", "message": "trade EA not ready — cannot execute trades", "latency_ms": 55 } ] } ``` ### POST /v1/orders/close Close across several accounts by intent rather than by ticket. Tickets are per account, you do not have them, and fetching them first means a second round trip against a list that goes stale when a stop fires. So this takes a selector and resolves the tickets itself: one lookup per account, then one close per match. At most 20 accounts, and 20 orders per account; matches past the cap come back skipped rather than being quietly dropped. Parameters: - `defaults`: Selector values every account inherits: symbol, symbol_match, side, kind, magic, volume, slippage. - `accounts` (required): One entry per account. Each is a selector, or an explicit tickets list, never both on the same account. - `symbol` (required): Required. The symbol to close, as your broker names it. * closes every symbol and must be typed literally: an omitted symbol is a 400, never a silent close-everything. - `symbol_match`: exact (default) matches as given. base also accepts a broker suffix, so EURUSD reaches EURUSD.sd and EURUSDm. A suffix is separator-led (.sd) or at most two alphanumerics (m), so EUR never matches EURUSD. - `kind`: position (default) closes open positions only, pending deletes pending orders only, any does both. The default keeps a routine close from silently deleting resting orders. - `side`: long, short, or any (default). - `volume`: Partial close volume, applied to each matched position and subject to the symbol's volume step. Omit for a full close. - `tickets`: Close exactly these tickets on this account, skipping the lookup. Tickets go stale, so prefer a selector unless you read them moments ago. - `require_reachable`: Reject the whole batch up front if any account has no terminal, instead of reporting that account as unreachable. Request body: ```json { "defaults": { "symbol": "EURUSD", "side": "long" }, "accounts": [ { "account_id": "6fcb1e23-8ea8-4674-aa62-3d48fd08f309" }, { "account_id": "a91b0d47-2c31-4f8a-9d76-1e5b0c3a7f42", "symbol": "EURUSD.sd" }, { "account_id": "c73d55e2-90b4-4a17-8f3c-6d2e9a1b4c85", "tickets": [123456, 123457] } ] } ``` 200 response: ```json { "batch_id": "b_01J8Z5N2R7T4W1", "idempotent_replay": false, "summary": { "accounts": 3, "matched": 4, "closed": 3, "failed": 1, "unknown": 0, "accounts_unknown": 0 }, "results": [ { "account_id": "6fcb1e23-8ea8-4674-aa62-3d48fd08f309", "platform": "mt5", "status": "closed", "matched": 2, "closed": 2, "message": "", "latency_ms": 940, "results": [ { "ticket": 1234567, "symbol": "EURUSD", "type": "Buy", "kind": "position", "volume": 0.10, "status": "closed", "retcode": 10009, "retcode_description": "TRADE_RETCODE_DONE", "price": 1.08430 } ] }, { "account_id": "c73d55e2-90b4-4a17-8f3c-6d2e9a1b4c85", "platform": "mt4", "status": "nothing_matched", "matched": 0, "closed": 0, "message": "", "latency_ms": 210, "results": [] } ] } ``` Symbol suffixes are per broker: EURUSD, EURUSD.sd and EURUSDm are all live in the fleet, so one defaults.symbol across mixed brokers will partly fail by design. Override symbol per leg to fix it, or on a close use symbol_match: "base" to let one selector reach all three spellings. ## Related - [Balance & top-ups](https://fxsocket.com/docs/api/wallet.md) --- # Balance and top-ups Source: https://fxsocket.com/docs/api/wallet Card subscriptions renew themselves; a one-off crypto payment never does. The prepaid balance is what closes that gap: top it up in crypto and it pays for each connected account as its month comes due, on its own date. These endpoints do that headlessly, with no hosted widget, so your own tooling can quote a top-up, get a deposit address and watch for the credit. Base URL: `https://api.fxsocket.com/v1` The prepaid balance, headless. Top up in crypto and the balance pays for account seats (€12 per connected account per month) and balance-funded private servers as they come due, which is what makes a crypto customer auto-renewing without anyone being asked to pay again. Minimum €10 per top-up, maximum €500, and the balance itself is capped at €1,000. Credit does not expire. Reading the balance works with a read-only key; creating a top-up needs the full key. ### GET /v1/wallet Balance, anything asked for but not yet landed, and what the balance owes over the next 30 days. Seats and private servers are projected together because they share the one balance, and looking at either alone would call a doomed month healthy. Only occupied seats appear: an empty paid slot is released unbilled when its date passes, so it is not money owed. 200 response: ```json { "balance_eur_cents": 2400, "pending_topups": [], "upcoming": [ { "when": "2026-10-01T09:12:00Z", "amount_eur_cents": 1200, "kind": "seat", "label": "VTMarkets-Demo 1234567" }, { "when": "2026-10-15T09:12:00Z", "amount_eur_cents": 1200, "kind": "seat", "label": "ICMarkets-Live 7654321" } ], "upcoming_total_eur_cents": 2400, "shortfall_eur_cents": 0, "covers_upcoming": true } ``` ### GET /v1/wallet/assets What a top-up of this size can be paid in, one row per coin-and-chain pair, each with the asset amount that size currently costs. Call it before creating a top-up and pass a pair back verbatim: which assets are offered, and how much of each, both depend on the amount. Prefer an is_stable pair for anything but an immediate payment, since a stablecoin quote barely moves inside the 30-minute window and a volatile one can. Parameters: - `amount_eur_cents` (required): The top-up size, in EUR cents. Out-of-bounds amounts are a 400. 200 response: ```json [ { "asset_code": "USDC", "asset_name": "USD Coin", "blockchain_code": "ETH", "blockchain_name": "Ethereum", "is_evm": true, "is_stable": true, "amount": "27.42", "decimals": 6, "display_decimals": 2 } ] ``` ### POST /v1/wallet/topup Create a top-up and get the address to send to plus exactly how much of the asset to send. Take asset_code and blockchain_code from GET /v1/wallet/assets for the same amount; send only that asset, on that chain, to that address. Under-paying credits only what arrives, because balance is stored value rather than a fixed purchase; over-paying credits the extra, and paying in several transactions works, each credited as it confirms. Parameters: - `amount_eur_cents` (required): €10 to €500, in cents. - `asset_code` (required): From GET /v1/wallet/assets, e.g. USDC. - `blockchain_code` (required): From the same row, e.g. ETH. - `is_evm`: Only for Web3 / wallet-connect flows. Leave false to be handed a plain deposit address. Request body: ```json { "amount_eur_cents": 2500, "asset_code": "USDC", "blockchain_code": "ETH", "is_evm": false } ``` 201 response: ```json { "id": 4417, "status": "pending", "amount_eur_cents": 2500, "credited_eur_cents": 0, "deposit_address": "0x9f3a...c4e5", "deposit_amount": "27420000", "deposit_amount_decimal": "27.42", "asset_code": "USDC", "blockchain_code": "ETH", "expires_at": "2026-09-11T14:42:00Z" } ``` ### GET /v1/wallet/topup/{id} Whether the deposit has landed. status is pending, partial, paid or failed, and credited_eur_cents is what has actually arrived, which sits below amount_eur_cents while a payment is short. A pending order reserves nothing: once expires_at passes it is marked failed and the invoice is cancelled at the provider, so the address stops being payable against a quote we no longer honour. Coin that arrives after that is still credited for whatever it was worth. 200 response: ```json { "id": 4417, "status": "paid", "amount_eur_cents": 2500, "credited_eur_cents": 2500, "deposit_address": "0x9f3a...c4e5", "deposit_amount": "27420000", "deposit_amount_decimal": "27.42", "asset_code": "USDC", "blockchain_code": "ETH", "expires_at": "2026-09-11T14:42:00Z" } ``` ### GET /v1/subscription Plan and status, how many account seats are paid for and how many are in use, when the current period ends, and the balance with whatever it owes next. Seats do not share one renewal date: each renews a calendar month after it was bought, so seat_details lists them individually, and account_id is null on a slot that is paid for but not currently in use. wallet is reported whether or not the plan itself is balance-funded, since a card customer can still hold credit, and is null only where the wallet is switched off; next_charge_eur_cents is what the BALANCE owes and is null when it owes nothing. 200 response: ```json { "plan": "per_account", "status": "active", "paid_access": true, "billing_provider": "balance", "cancel_at_period_end": false, "seats": { "total": 2, "used": 2, "bonus": 0 }, "seat_details": [ { "id": "4d1e...", "paid_until": "2026-10-01T09:12:00Z", "status": "active", "account_id": "6fcb1e23-..." }, { "id": "8b02...", "paid_until": "2026-10-15T09:12:00Z", "status": "active", "account_id": "a91b0d47-..." } ], "current_period_end": "2026-10-15T09:12:00Z", "grace_ends_at": null, "wallet": { "balance_eur_cents": 2400, "next_charge_eur_cents": 1200, "next_charge_at": "2026-10-01T09:12:00Z", "covers_next_charge": true } } ``` The balance moves when the signed postback confirms the transaction, not when POST /v1/wallet/topup returns. Poll the top-up or GET /v1/wallet rather than treating the 201 as payment. ## Related - [Multi-account execution](https://fxsocket.com/docs/api/batch-orders.md) --- # MetaTrader MCP server Source: https://fxsocket.com/docs/mcp Give an AI agent read access to your MetaTrader 4 and MetaTrader 5 accounts. The FxSocket MCP server lets Claude, Cursor, VS Code and any other Model Context Protocol client answer questions about your trading: balance and equity across accounts, what is open right now, how last month went, live quotes and price history. It is read-only. No tool can place, modify or close an order. Server URL: `https://mcp.fxsocket.com/mcp` ## 1. Create a read-only API key On the API Key page (https://app.fxsocket.com/dashboard/api-key), create a read-only key. It starts with `fxs_ro_`, can call every tool here, and cannot trade through any other endpoint either. Name it and limit it to the accounts the agent should see, and the agent never learns the others exist. Your full `fxs_live_` key works too, but an agent has no use for one. ## 2. Connect your client Clients that take a remote server URL and a header connect directly. Clients that only start local servers, such as Claude Desktop, use the Docker image (see below). Claude Code: ```bash claude mcp add --transport http fxsocket https://mcp.fxsocket.com/mcp \ --header "X-API-Key: fxs_ro_xxx" ``` Cursor, ~/.cursor/mcp.json: ```json { "mcpServers": { "fxsocket": { "url": "https://mcp.fxsocket.com/mcp", "headers": { "X-API-Key": "fxs_ro_xxx" } } } } ``` VS Code, .vscode/mcp.json: ```json { "servers": { "fxsocket": { "type": "http", "url": "https://mcp.fxsocket.com/mcp", "headers": { "X-API-Key": "fxs_ro_xxx" } } } } ``` Claude Desktop, claude_desktop_config.json: ```json { "mcpServers": { "fxsocket": { "command": "docker", "args": ["run", "-i", "--rm", "-e", "FXSOCKET_API_KEY", "fxsocket/mcp"], "env": { "FXSOCKET_API_KEY": "fxs_ro_xxx" } } } } ``` Any other client works the same way: point it at `https://mcp.fxsocket.com/mcp` with the key in an `X-API-Key` header (`Authorization: Bearer` is accepted too), or run the Docker image as a local server. ## Tools Eight tools, all read-only. Each one is shaped around a question rather than an endpoint, so "what is open across my accounts" is one call that reads every terminal at once. - `list_accounts`: Every account the key can see, with its id, nickname, platform, server, login and connection status, optionally with balance, equity and totals per currency. Agents call it first. - `get_account`: One account in full: balance, equity, margin, margin level and leverage, account settings such as the stop-out level, and terminal health. - `get_open_positions`: Open positions and pending orders across accounts, filterable by symbol and type, with floating profit, swap and totals per currency. - `get_trade_history`: Closed trades for a period (the last 7 days by default, up to 366), with wins, losses, win rate, net profit, the best and worst trade, and a breakdown by symbol. - `search_symbols`: The broker's exact symbol name. EURUSD is EURUSD.sd or EURUSDm at some brokers, so agents look it up before asking for prices. - `get_quotes`: Live bid, ask and spread for up to 20 symbols. - `get_symbol_info`: The contract specification: digits, contract size, tick value, volume limits, swap rates, commissions and trading sessions. - `get_price_history`: OHLC candles for a symbol and timeframe, up to 500 bars per call. ## What you can ask - "What is my total equity across all accounts, per currency?" - "Which open positions are in the red right now, and by how much?" - "What was my win rate on XAUUSD last month, and what was my worst trade?" - "Compare the EURUSD spread on each of my brokers." - "Pull the last 200 H1 candles of GBPUSD and describe the trend." ## Read-only by design The server cannot trade because of what its code can reach, not because of a setting: every tool reads from the terminal and none of them can send an order. So a confused or manipulated agent still cannot open, change or close a position. Money is reported in each account's deposit currency and never added across currencies; the tools return totals per currency so the model does not have to do that arithmetic. Times are broker server time, as everywhere else in the API. Limits: 60 requests a minute per user, up to 50 accounts and 300 order or trade rows in one reply. Counts and totals always cover everything; only the row lists are cut. ## Run it locally with Docker The `fxsocket/mcp` image runs the server as a local stdio process, for clients that start their servers themselves. It is a small relay, one Python file with no dependencies, that passes each message to `mcp.fxsocket.com` with your key. The tools and your data still come from FxSocket, so the image never needs updating when tools change. Published for amd64 and arm64. ```bash FXSOCKET_API_KEY=fxs_ro_xxx docker run -i --rm -e FXSOCKET_API_KEY fxsocket/mcp ``` Docker Hub: https://hub.docker.com/r/fxsocket/mcp · Source on GitHub (MIT): https://github.com/fxsocket-com/FxSocket-MCP ## Protocol details - Transport: Streamable HTTP, POST only, JSON responses. Stateless, with no session to keep alive. - Protocol versions: 2026-07-28 (per-request metadata, no handshake) and 2025-03-26 through 2025-11-25 (the `initialize` handshake). - Authentication: the same API keys as the [platform API](https://fxsocket.com/docs/api.md), in `X-API-Key` or `Authorization: Bearer`. - Not yet supported: the web connectors in claude.ai and ChatGPT, which sign in with OAuth rather than a header. Claude Desktop works today through the Docker image. ## Related - [Docs for AI coding agents](https://fxsocket.com/docs/ai-agents.md) - [MT5 account data API](https://fxsocket.com/docs/mt5/account-data.md) - [Platform API](https://fxsocket.com/docs/api.md) --- # Docs for AI coding agents Source: https://fxsocket.com/docs/ai-agents Claude Code, Cursor, Codex and GitHub Copilot write working FxSocket code when they read the docs, and plausible-looking broken code when they guess. Everything on this page exists so your agent reads instead: a rules file for your project, every docs page as Markdown, the whole reference in one file, and a read-only MCP server for your live accounts. ## 1. Add the rules file to your project A short AGENTS.md section covering what agents get wrong without it: broker-specific symbol names, checking `retcode` instead of the HTTP status, broker server time, and never retrying an order blindly. Codex, Cursor, GitHub Copilot, Windsurf and Zed read AGENTS.md from the project root. Claude Code reads CLAUDE.md, so import the same file there. Append to AGENTS.md: ```bash curl -s https://fxsocket.com/docs/ai-agents/rules.md >> AGENTS.md ``` Claude Code: ```bash echo "@AGENTS.md" >> CLAUDE.md ``` What it adds, also served on its own at https://fxsocket.com/docs/ai-agents/rules.md: ```markdown # FxSocket This project uses FxSocket, a cloud API for MetaTrader 4 and MetaTrader 5. Every linked broker account runs in its own MT4 or MT5 terminal in FxSocket's cloud and is controlled over REST and WebSocket. Read the docs instead of guessing endpoints or field names: - All docs in one file: https://fxsocket.com/llms-full.txt - Any docs page as Markdown: append .md to its URL, e.g. https://fxsocket.com/docs/mt5/trading.md ## SDKs and keys - Prefer the official SDKs over raw HTTP. Python: `pip install fxsocket` (`Client`, `AsyncClient`). Node.js / TypeScript: `npm install @fxsocket/sdk` (`FxSocket`). One interface covers MT4 and MT5. - Both SDKs read the key from the `FXSOCKET_API_KEY` environment variable. Never hardcode an API key or commit one. - `fxs_live_` keys can trade. `fxs_ro_` keys are read-only: GET endpoints only, and they can be limited to selected accounts. Use a read-only key for anything that only reads. ## URLs and auth - Platform API: https://api.fxsocket.com/v1 (accounts, multi-account orders, wallet). OpenAPI spec: https://api.fxsocket.com/v1/schema - Per-account terminal API: https://api.fxsocket.com/mt5/{account_id}/... or https://api.fxsocket.com/mt4/{account_id}/... where {account_id} is the UUID from GET /v1/accounts. Each account serves its own OpenAPI spec at .../api-doc/openapi.json (no key needed). - Send the key in the `X-API-Key` header. Terminal routes do not accept `Authorization: Bearer`; /v1 and the MCP server do. - WebSocket: wss://api.fxsocket.com/mt5/{account_id}/ws?api_key=... (the query parameter is the only auth WebSocket supports). One socket per account, topics prices, bars, account, positions, trades, terminal. Prefer it over polling REST. ## Before sending orders - A new account reads `connecting` for 1 to 3 minutes. Wait for `connected` on GET /v1/accounts/{account_id} and `ready` on GET /status before trading. - Symbol names are broker-specific (EURUSD, EURUSD.sd, EURUSDm). Get the exact name from GET /symbols; never assume the plain name. - Read GET /SymbolInfo first: keep volume within volumeMin, volumeMax and volumeStep, and round prices to `digits`. - Timestamps are broker server time even though they end in Z. Convert with GET /ServerTimezone: utc = serverTime - utcOffsetSeconds. ## Order results - HTTP 200 from OrderSend, OrderModify or OrderClose only means the terminal answered. Check `success` and `retcode`: 10009 is done, 10008 is placed, anything else is a rejection (report `retcodeDescription`). 10025 on a modify means nothing changed because the values were already set. - A 500 or 504 with an error envelope can still mean the order executed. Check GET /OpenedOrders before sending again; never retry an order blindly. - To trade many accounts at once use POST /v1/orders and POST /v1/orders/close (at most 20 legs or accounts, snake_case fields, unknown fields are a 400). Send an `Idempotency-Key` header so a retry cannot trade twice. ## Errors - 401 `MRPC_UNAUTHORIZED`: missing or wrong key. 404: unknown account_id or path. - Other errors use `{"error", "message", "command_id"}`. A 5xx without that envelope means the terminal is restarting (for example right after a key rotation): retry with backoff. Trading routes can return 503 briefly after a terminal starts. - /v1 answers 429 with a `Retry-After` header when rate limited. Wait that long. ## Safety - Build and test against a demo account. - Do not place, modify or close orders on a live account unless the user explicitly asks for it. ``` ## 2. Give it the docs as Markdown - Every docs page has a Markdown twin: add .md to the URL, for example https://fxsocket.com/docs/mt5/trading.md. Agents that send `Accept: text/markdown` get it from the normal URL. - The Copy page menu at the top of every docs page copies that Markdown, or opens the page in ChatGPT or Claude to ask about it. - https://fxsocket.com/llms.txt is the index. https://fxsocket.com/llms-full.txt is the whole reference in one file (MT5, MT4, platform API and MCP) for agents that should read everything up front. Cursor can also index it as a docs source for @Docs. ```bash curl -H "Accept: text/markdown" https://fxsocket.com/docs/mt5/trading ``` ## 3. Generate clients from OpenAPI For exact field names and generated types: the platform API spec at https://api.fxsocket.com/v1/schema, and each account's own spec at https://api.fxsocket.com/mt5/{account_id}/api-doc/openapi.json (or /mt4/). Neither needs a key. ## 4. Let it see your accounts The docs tell an agent how the API works. The [MCP server](https://fxsocket.com/docs/mcp.md) shows it your actual accounts: which symbols your broker lists and how they are spelled, what is open, recent trades and prices. It is read-only, so an agent can explore while it builds without being able to trade. ```bash claude mcp add --transport http fxsocket https://mcp.fxsocket.com/mcp \ --header "X-API-Key: fxs_ro_xxx" ``` ## Keep it on a short leash The rules tell the agent to build against a demo account and never to trade a live account unless you ask. Give it a read-only `fxs_ro_` key unless the code it writes has to trade: a read-only key cannot place an order however hard the agent tries. ## Try it Paste this into your agent to check it is set up: ``` Read https://fxsocket.com/llms-full.txt first. Then write a Python script with the fxsocket SDK that lists my accounts and prints balance and equity for each one. Read the API key from the FXSOCKET_API_KEY environment variable. Do not place any orders. ``` ## Related - [MCP server](https://fxsocket.com/docs/mcp.md) - [MetaTrader 5 API](https://fxsocket.com/docs/mt5.md) - [Platform API](https://fxsocket.com/docs/api.md)