Quickstart
Create an API key, connect a master and a follower account, create a copier and attach the follower, then check that it's copying.
This guide takes about ten minutes, most of it waiting for two MetaTrader terminals to start. You will connect two accounts, copy the trades of one to the other, and read back the follower's status and the copier's events.
You need a plan with at least two account slots and two MetaTrader 4 or 5 accounts: one whose trades are copied (the master) and one that copies them (the follower). Demo accounts work.
The examples use cURL with jq, TypeScript with the built-in fetch of Node.js 18 or later, and Python with the requests package.
1. Create an API key
- Sign in at app.algotradertools.com.
- Open API keys in the sidebar and create a key. Leave all four scopes selected.
- Copy the key. It is shown only once.
2. Export the key
Keep the key out of your source code. The examples read it from an environment variable:
export ATT_API_KEY="att_…"The TypeScript and Python examples share a small helper that sends the key, encodes JSON and turns error responses into exceptions. Save it next to your script:
// att.ts
const API = "https://api.algotradertools.com/v1";
export async function att(method: string, path: string, body?: unknown) {
const response = await fetch(`${API}${path}`, {
method,
headers: {
Authorization: `Bearer ${process.env.ATT_API_KEY}`,
...(body === undefined ? {} : { "Content-Type": "application/json" }),
},
body: body === undefined ? undefined : JSON.stringify(body),
});
if (response.status === 204) return null;
const payload = await response.json();
if (!response.ok) {
throw new Error(`${payload.code}: ${payload.detail} (request ${payload.request_id})`);
}
return payload;
}Put the TypeScript examples in a file such as quickstart.ts and run it with npx tsx quickstart.ts.
3. Connect the master and the follower
Connect the master with its investor (read-only) password, since its trades only need to be read. The follower receives trades, so it needs its master (trading) password. Each password is stored encrypted with the terminal that runs the account and is never shown again.
curl https://api.algotradertools.com/v1/accounts \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51234567,
"password": "<investor password>",
"credential_kind": "investor",
"nickname": "Gold master"
}'
curl https://api.algotradertools.com/v1/accounts \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51239876,
"password": "<master password>",
"credential_kind": "master"
}'Each request returns 201 Created with the new account, still in connecting:
{
"id": "4f6c2a1e-8b3d-4e7a-9c5f-1d2e3a4b5c6d",
"object": "account",
"name": "Gold master",
"nickname": "Gold master",
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51234567,
"credential_kind": "investor",
"can_trade": false,
"status": "connecting",
"error": null,
"released": false,
"role": null,
"figures": null,
"created_at": "2026-10-25T14:03:51.204Z"
}Copy the server name exactly as MetaTrader shows it in its login window. A wrong server name fails with 400 server_not_found, and a wrong password with 400 invalid_credentials.
4. Wait until both are connected
Each terminal starts and logs in to the broker, which takes two to three minutes. Check the account every 15 seconds or less often until its status is connected. If it turns to error instead, the error field says why.
MASTER_ID=4f6c2a1e-8b3d-4e7a-9c5f-1d2e3a4b5c6d
FOLLOWER_ACCOUNT_ID=9b2e7d4c-1a3f-4c8e-b5d6-7e8f9a0b1c2d
for id in $MASTER_ID $FOLLOWER_ACCOUNT_ID; do
until [ "$(curl -s https://api.algotradertools.com/v1/accounts/$id \
-H "Authorization: Bearer $ATT_API_KEY" | jq -r .status)" != "connecting" ]; do
sleep 15
done
done5. Create a copier
A copier watches its master and copies the master's trades to its followers. Create one for the master you just connected:
curl https://api.algotradertools.com/v1/copiers \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Gold strategy", "master_id": "'$MASTER_ID'" }'{
"id": "c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
"object": "copier",
"name": "Gold strategy",
"is_active": true,
"master_id": "4f6c2a1e-8b3d-4e7a-9c5f-1d2e3a4b5c6d",
"master": {
"id": "4f6c2a1e-8b3d-4e7a-9c5f-1d2e3a4b5c6d",
"name": "Gold master",
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51234567,
"status": "connected"
},
"followers": [],
"open_copies": 0,
"created_at": "2026-10-25T14:08:30.512Z",
"updated_at": "2026-10-25T14:08:30.512Z"
}6. Attach the follower
Attach the follower account and give it the rules it should copy with. The follower below sizes its lots by its equity compared with the master's, trades at most 2 lots per copy, and only copies XAUUSD on weekdays from 07:00 to 21:00 London time. Every rule you leave out keeps its default.
COPIER_ID=c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f
curl https://api.algotradertools.com/v1/copiers/$COPIER_ID/followers \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"account_id": "'$FOLLOWER_ACCOUNT_ID'",
"lot_mode": "equity_ratio",
"lot_value": 1,
"max_lot": 2,
"symbol_filter": "include",
"symbols": ["XAUUSD"],
"sessions": [{ "days": [0, 1, 2, 3, 4], "start": "07:00", "end": "21:00" }],
"timezone": "Europe/London"
}'The response is the new follower, with every rule filled in. Its status is null until the copier engine first reports on it, usually within a few seconds:
{
"id": "e2f4a6b8-c0d2-4e46-8a8c-9e0f1a2b3c4d",
"object": "follower",
"copier_id": "c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f",
"account_id": "9b2e7d4c-1a3f-4c8e-b5d6-7e8f9a0b1c2d",
"account": {
"id": "9b2e7d4c-1a3f-4c8e-b5d6-7e8f9a0b1c2d",
"name": "MT5 51239876",
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51239876,
"status": "connected"
},
"is_active": true,
"magic": 1840273951,
"lot_mode": "equity_ratio",
"lot_value": 1,
"adjust_contract_size": true,
"below_minimum": "minimum",
"max_lot": 2,
"reverse": false,
"copy_stops": true,
"max_slippage_pips": null,
"max_delay_seconds": 60,
"copy_existing": false,
"symbol_filter": "include",
"symbols": ["XAUUSD"],
"sessions": [{ "days": [0, 1, 2, 3, 4], "start": "07:00", "end": "21:00" }],
"timezone": "Europe/London",
"symbol_map": {},
"status": null,
"created_at": "2026-10-25T14:09:02.118Z",
"updated_at": "2026-10-25T14:09:02.118Z"
}Positions the master already had open aren't copied unless you set copy_existing. Without it, only what the master opens from now on is copied.
7. Check that it's copying
Read the copier. Each of its followers has a live status from the copier engine:
curl https://api.algotradertools.com/v1/copiers/$COPIER_ID \
-H "Authorization: Bearer $ATT_API_KEY" | jq '.followers[] | {account: .account.name, status}'{
"account": "MT5 51239876",
"status": {
"state": "copying",
"message": "",
"master_connected": true,
"follower_connected": true,
"open_copies": 0,
"last_event_at": null,
"balance": 5000.0,
"equity": 5031.2,
"currency": "USD",
"heartbeat_at": "2026-10-25T14:09:20.004Z",
"engine_online": true
}
}Now open a gold trade on the master. Within a second or so, the copy shows up in the copier's events, which are listed newest first:
curl "https://api.algotradertools.com/v1/copiers/$COPIER_ID/events?limit=5" \
-H "Authorization: Bearer $ATT_API_KEY"{
"object": "list",
"data": [
{
"id": 48213,
"object": "copy_event",
"follower_id": "e2f4a6b8-c0d2-4e46-8a8c-9e0f1a2b3c4d",
"account_id": "9b2e7d4c-1a3f-4c8e-b5d6-7e8f9a0b1c2d",
"master_ticket": 3518820446,
"action": "open",
"ok": true,
"message": "Opened 0.48 XAUUSD (buy) at 2391.84.",
"detail": {
"symbol": "XAUUSD",
"side": "buy",
"volume": 0.48,
"stopLoss": 2380.0,
"takeProfit": null,
"price": 2391.84,
"retcode": 10009,
"outcome": "applied",
"ticket": 3518820991
},
"received_at": "2026-10-25T14:21:07.211Z",
"engine_ms": 0.31,
"execution_ms": 186.4,
"total_ms": 186.7
}
],
"has_more": false,
"next_cursor": null
}The master traded 1 lot with 10,318.40 USD equity. The follower has 5,031.20 USD equity, so it traded 1 × 5,031.20 ÷ 10,318.40 = 0.4876 lots, rounded down to the broker's lot step. That gives 0.48 lots.
If a request fails
Errors are JSON problem details with a code such as invalid_api_key, plan_limit_reached or validation_failed. For validation_failed, errors names each field that needs fixing. See Errors for every code.
8. Pause, resume and clean up
- To pause one follower, send
{ "is_active": false }withPATCH /v1/copiers/{copier_id}/followers/{follower_id}. To pause the whole copier, send the same body withPATCH /v1/copiers/{copier_id}. Sendtrueto resume. See Copiers. - Delete the copier with
DELETE /v1/copiers/{copier_id}. Add?close_positions=trueto close the copies it opened as well. - Disconnect an account with
DELETE /v1/accounts/{account_id}once no copier uses it.