MT4 Copy Trading API: Replicating Trades Across Brokers Without Touching MetaTrader Internals
Most MT4 copy trading setups rely on server-side bridges or plugins that connect directly to broker servers. This worked fine when you had 10 followers on a single broker. It breaks down when you have 100 followers across 20 brokers—each with different execution speeds, symbol mappings, and API quirks.
The problem isn't just technical debt. Server-side tools lock you into specific broker relationships. They require custom integrations for each liquidity provider. They introduce single points of failure that can drop hundreds of trades during a network hiccup. And they scale linearly: more followers means more broker connections, more CPU cycles, more things that can break.
CopyBridge solves this with a different architecture. Signal providers install a Master EA on their MT4/MT5 platform that sends trade events to our API. Followers install a Copier EA on their own broker—any broker that supports standard MT4/MT5—and the EA polls our API for new trades. No broker-to-broker connections. No server-side plugins. The API is the single source of truth.
Why the Master EA + API Model Wins
Traditional copy trading platforms require broker partnerships because they need direct server access. If your followers want to trade on IC Markets, Pepperstone, and FTMO simultaneously, you need three separate integrations. Each broker has subtle differences in how they handle pending orders, partial closes, or hedge positions.
The Master EA approach flips this. The provider's EA watches for trade events (OrderSend, OrderClose, OrderModify) and posts them to the API:
curl -X POST https://api.copybridge.io/api/v1/trades \
-H "X-API-Key: <your-master-key-uuid>" \
-H "Content-Type: application/json" \
-d '{
"action": "OPEN",
"symbol": "EURUSD",
"type": "BUY",
"lots": 0.1,
"price": 1.0850,
"sl": 1.0800,
"tp": 1.0950,
"magic": 987654,
"ticket": 12345678
}'
action is one of OPEN, CLOSE, MODIFY; type is BUY or SELL. action, symbol, type, lots, price and ticket are required — anything else is a 400.
The API validates the request, stores the trade, and makes it available to all authorized followers. Each Copier EA polls every 2 seconds and replicates trades locally. If a follower's broker rejects an order due to insufficient margin, only that follower sees the error. The master trade continues. Other followers continue. No cascade failures.
This architecture gives you broker neutrality by default. Followers can use any MT4/MT5 broker without you writing a single line of integration code. They can switch brokers without affecting your signal service. You can white-label the platform and let your customers choose their own liquidity providers.
What the API Actually Does
The MT4 copy trading API handles four core operations:
Trade Open: Master EA detects a new position and sends an OPEN action with symbol, direction, lot size, entry price and SL/TP. The API returns the stored row — including its id and its seq, the monotonic cursor followers poll on. The master's own ticket is what links every later event to this trade.
Trade Close: Master EA detects position exit and sends a CLOSE action for the same ticket. Copier EAs see this on next poll and close their local positions.
Trade Update: Master EA detects SL/TP modification or partial close and sends a MODIFY action. The API stores it as a further row against the same ticket. Copier EAs adjust their positions to match.
Trade Sync: Copier EA calls GET /api/v1/trades/snapshot to get the current state — the latest OPEN for every ticket that has no CLOSE, plus the provider's maximum seq. This handles reconnections gracefully: if a Copier EA crashes or loses network, it fetches all open trades on restart and reconciles.
Here's a Copier EA polling example in pseudo-MQL4:
// Inside OnTimer()
string url = "https://api.copybridge.io/api/v1/trades?since_seq="
+ IntegerToString(lastSeq);
string headers = "X-Subscriber-Key: <your-subscriber-key-uuid>\r\n";
string result = WebRequest("GET", url, headers, 5000);
// Parse JSON, iterate trades
for(int i=0; i<ArraySize(trades); i++) {
int local_ticket = FindLocalTicket(trades[i].ticket);
if(trades[i].action == "OPEN" && local_ticket == 0) {
// No local position—open one
OrderSend(trades[i].symbol, trades[i].type,
trades[i].lots, trades[i].price,
3, trades[i].sl, trades[i].tp);
}
else if(trades[i].action == "MODIFY" && local_ticket != 0) {
// Trade was modified—update SL/TP
OrderModify(local_ticket, OrderOpenPrice(),
trades[i].sl, trades[i].tp, 0);
}
// Advance the cursor so the next poll only returns new rows
if(trades[i].seq > lastSeq) lastSeq = trades[i].seq;
}
The API doesn't execute trades. It stores and distributes trade intent. Execution happens locally on each follower's broker, which means you inherit that broker's fill quality, slippage, and latency. A follower on a London VPS with a Tier-1 broker gets better fills than a follower on residential internet with a bucket shop. This is a feature, not a bug—followers choose their own execution quality.
Latency: What to Expect
The polling interval dominates, not the API. The published contract is under 50ms of API processing plus a 2-second maximum polling interval — trades copied within seconds of the master's fill. On top of that you inherit your own broker's OrderSend execution time.
There is no faster setting to turn up. The 2-second interval is a compile-time constant in both the MT4 and MT5 Copier EAs, not an input parameter. The API rate limit is 200 requests per minute, applied per IP across all /api/ endpoints.
Compare this to server-side bridges that promise "instant" replication. They still need to:
- Detect the master trade (polling the broker's trade server)
- Map symbol names between brokers (EURUSD vs EURUSD.a vs EURUSD.m)
- Calculate lot sizes per follower's risk settings
- Send orders to each follower's broker
- Handle rejections and retries
Each step adds latency. Server-side bridges are faster for single-broker setups but slower and more brittle when you have followers across multiple brokers with different symbol conventions and margin requirements.
MT4 vs MT5 Differences
The API is platform-agnostic. Master EAs and Copier EAs exist for both MT4 and MT5. The trade data format is identical. A master account on MT4 can have followers on MT5 and vice versa.
There is no netting layer anywhere in the stack. Every master ticket maps to exactly one local order on each follower, keyed by that ticket, on both platforms. Opposite positions in the same symbol are never combined into a net position by CopyBridge — whatever your MT4 broker does with them is your broker's own behaviour.
Symbols are passed through verbatim: the Copier EA selects the master's symbol name on the local broker and skips the trade if that symbol isn't available. There is no symbol-mapping table. What the EA does expose is a per-pair on/off toggle in its inputs (InpTradeEURUSD and friends), covering eight major FX pairs; anything outside that set is skipped on open, fail-safe.
Broker Neutrality in Practice
The biggest advantage of API-driven copy trading is that you never touch your followers' broker credentials. Followers install the Copier EA themselves. They input their subscriber key (generated in the dashboard). The EA authenticates directly to the CopyBridge API. No FTP uploads to broker servers. No custom plugins. No risk of credential leaks.
This matters for compliance. Many jurisdictions restrict how you can handle client funds and broker access. With CopyBridge, you're distributing trading signals via API. Followers execute trades on their own accounts with their own brokers. You're not acting as an introducing broker or white-label partner unless you choose to be.
It also matters for scalability. Server-side bridges require you to maintain relationships with every broker your followers might use. Each broker has its own onboarding process, integration timeline, and support headaches. With client-side EAs, followers bring their own brokers. You focus on generating good signals. They focus on execution quality and broker selection.
Sandbox Mode for Testing
Before you push trades to live accounts, test in sandbox mode. Sandbox requests go to the same endpoints, but trades from a sandbox provider are stored with is_sandbox set — and every GET /api/v1/trades variant filters those rows out. Sandbox trades therefore never reach a Copier EA at all. A sandbox provider also bypasses the platform's risk caps (symbol whitelist, lot ceiling, open-position and open-rate limits), so staging data can't be blocked by production safety rules.
Sandbox mode lets you:
- Test Master EA integration without risking real trades
- Verify webhook delivery and signature validation — sandbox deliveries carry
"sandbox": truein the payload
Example sandbox request:
curl -X POST https://api.copybridge.io/api/v1/trades \
-H "X-API-Key: <your-master-key-uuid>" \
-H "Content-Type: application/json" \
-d '{
"action": "OPEN",
"symbol": "EURUSD",
"type": "SELL",
"lots": 0.5,
"price": 1.0850,
"ticket": 99999
}'
There is no separate key format for sandbox versus live — keys are plain UUIDs either way. Sandbox is a flag on the provider account itself (set by an integrator), so the same key works in both modes; it's the account's mode that determines whether a request lands in sandbox or production.
Authentication and Security
Provider accounts authenticate with X-API-Key headers. Subscriber accounts (followers) use X-Subscriber-Key. White-label integrators use X-Integrator-Key to provision and manage child provider accounts.
Keys are scoped to specific permissions. A subscriber key can read trades but not create them — POST /api/v1/trades requires a provider key. Subscriber keys are issued by the provider, via POST /api/v1/providers/me/followers or the dashboard. The integrator key's surface is child-provider CRUD under /api/v1/integrator/providers; no trade endpoint accepts it.
Webhooks—used to push trade events to your backend instead of polling—are secured with Standard Webhooks signing. Each delivery carries three headers: webhook-id, webhook-timestamp, and webhook-signature (format v1,{signature}). The signature covers webhook-id.webhook-timestamp.raw_body, HMAC-SHA256'd with the signing secret — decoded, not used as a raw string. Verify before processing to prevent spoofing:
import base64, hashlib, hmac
def verify_webhook(raw_body: bytes, headers: dict, secret: str) -> bool:
eid = headers.get('webhook-id', '')
ts = headers.get('webhook-timestamp', '')
sig = headers.get('webhook-signature', '').replace('v1,', '')
# secret is `whsec_` + base64 — strip the prefix and decode; the
# resulting bytes are the HMAC key, not the secret string itself.
key = base64.b64decode(secret[len('whsec_'):])
msg = f'{eid}.{ts}.{raw_body.decode("utf-8")}'.encode('utf-8')
expected = base64.b64encode(hmac.new(key, msg, hashlib.sha256).digest()).decode('ascii')
return hmac.compare_digest(sig, expected)
Full walkthrough, including the Node.js version and idempotency handling, is in the copy trading webhooks guide.
Building on the API
The API documentation covers the endpoints, authentication and rate limits, with curl and Node.js examples. The OpenAPI specification and the downloadable Postman collection live on the interactive API explorer.
If you're launching a signal service, the start a signal service guide walks through Master EA setup, dashboard configuration, and how to onboard your first subscribers. For white-label platforms—where you want to rebrand the entire stack and handle billing yourself—see the white-label trade copier overview.
Provider plans are priced by follower count, one master account each: Free (up to 2 followers), Starter $49/mo (50), Professional $149/mo (200), Business $399/mo (750), Enterprise $999/mo (2,500). White-label integrators pay per seat via Whop instead. No rev-share on follower subscriptions — CopyBridge charges the provider a flat platform fee and you keep every dollar your followers pay. You control pricing and customer relationships. We provide the infrastructure.
Start with the API explorer to test requests in your browser, or jump straight to the developer docs for integration details.