Followers
Attach accounts to a copier, set each one's rules for lot size, limits, direction, stops, symbols, symbol mapping and sessions, and read its live status.
A follower is an account that copies a copier's master, with its own rules for how it copies. Every rule has a default, so to attach an account you only need its ID. To read followers, your API key needs the copiers:read scope. To attach, change or remove them, it needs copiers:write.
Attach a follower
curl https://api.algotradertools.com/v1/copiers/c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f/followers \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"account_id": "9b2e7d4c-1a3f-4c8e-b5d6-7e8f9a0b1c2d",
"lot_mode": "multiplier",
"lot_value": 0.5,
"max_lot": 5
}'Send the account_id (required), any of the rules below, and optionally is_active. It defaults to true, and false attaches the follower paused. The response is 201 Created with the follower.
The account must be one of yours, and it must:
| Requirement | Code of the account_id error |
|---|---|
| Exist and belong to you | does_not_exist |
| Not be this copier's master | self_copy |
Be connected with its master password (can_trade: true) | read_only_account |
Be connected, not still connecting or released | account_not_connected |
| Not be the master of any copier | account_is_master |
| Not already copy this master, in this copier or another one | already_following |
| Be a hedging account (all MT4; MT5 hedging, not netting) | netting_account |
| Allow automated trading: brokers can switch it off for one account | automated_trading_off |
If the account doesn't meet a requirement, or a rule is invalid, the response is 400 validation_failed. The netting and automated-trading checks ask the account's terminal. If the terminal doesn't answer, the request fails with 503 terminal_unavailable. Try again shortly.
Retrying an attach is safe: if the first attempt went through, the second fails with already_following.
A new follower copies what the master opens after it was attached. Positions the master already has open are left alone, unless you set copy_existing.
Rules
| Field | Type | Default | Description |
|---|---|---|---|
lot_mode | multiplier, fixed, balance_ratio, equity_ratio or risk_percent | multiplier | How lots are sized. See Lot sizing |
lot_value | number | 1 | The multiplier, the fixed lot size or the risk percentage, depending on lot_mode. Above 0 and up to 1000, or up to 100 for risk_percent |
adjust_contract_size | boolean | true | Even out contract sizes between the two brokers |
below_minimum | minimum or skip | minimum | When the size comes out below the broker's minimum lot: trade the minimum, or skip the trade |
max_lot | number or null | null | The largest lot size a copy can have. Above 0 |
reverse | boolean | false | Trade the opposite direction |
copy_stops | boolean | true | Copy stop loss and take profit, including later changes |
max_slippage_pips | number or null | null | The slippage allowed when the copy is placed. null uses the broker's default. 0 or more |
max_delay_seconds | integer | 60 | How late a trade may still be copied, from 0 to 3600 seconds |
copy_existing | boolean | false | Also copy the positions and pending orders the master already has when the follower is attached |
copy_pending | boolean | false | Place the master's pending orders as pending orders too. See Pending orders |
symbol_filter | all, include or exclude | all | Which of the master's symbols are copied. See Symbols |
symbols | array of strings | [] | The master's symbol names that symbol_filter includes or excludes. Up to 200, each up to 32 characters |
sessions | array of sessions | [] | When new trades are copied. Empty means any time. See Trading sessions |
timezone | string | broker | Which clock the sessions times use. See Trading sessions |
symbol_map | object | {} | Master symbol to follower symbol, for names that don't match by themselves. Up to 200 entries |
Lot sizing
Each copy's size is worked out from the master's position when it opens:
lot_mode | Size of the copy | Example |
|---|---|---|
multiplier | The master's lots × lot_value | 0.5: the master trades 1.00 lot, the copy is 0.50 |
fixed | lot_value lots, whatever the master trades | 0.10: every copy is 0.10 lots |
balance_ratio | The master's lots × (follower balance ÷ master balance) × lot_value | 1: the master has 20,000 and trades 2.00 lots, the follower has 5,000, so the copy is 0.50 |
equity_ratio | As balance_ratio, with equity instead of balance | 1: the master's equity is 10,318.40 and the follower's 5,031.20, so 1.00 lot becomes 0.48 |
risk_percent | Sized so that the master's stop loss would lose lot_value percent of the follower's equity | 1 with 5,000 equity risks 50. With the stop 10.00 below a gold entry and 100 oz per lot, one lot would lose 1,000, so the copy is 0.05 lots |
Then:
- The size is rounded down to the follower broker's lot step and capped at its maximum lot.
- If it is below the broker's minimum lot,
below_minimumdecides:minimumtrades the minimum,skipskips the trade. - If
max_lotis set, the copy is capped at it.
Notes on the modes:
risk_percentneeds a stop loss: the master's trades without one are skipped.balance_ratioandequity_ratiocompare the two figures as they are, without converting currency. With a master in EUR and a follower in USD, the size is off by the exchange rate.adjust_contract_sizeapplies tomultiplier,balance_ratioandequity_ratio. Brokers size the same instrument differently: gold can be 100 oz a lot at one broker and 10 oz at another. Withadjust_contract_sizeon, a master lot of 100 oz counts as 10 follower lots of 10 oz each, and the mode's own factor applies on top.
Direction and stops
reverse: truesells when the master buys and buys when it sells, and swaps stop loss and take profit.copy_stops: truecopies the master's stop loss and take profit, and every later change to them. A new copy opens with them.
Execution
max_slippage_pipslimits how far the price may move between the request and the fill.nullleaves it to the broker.max_delay_secondssets how old a master trade may be and still get copied, for example after a terminal reconnects. Older trades are skipped.copy_existing: truealso copies the positions the master already has open when the follower is attached. It doesn't apply when a follower or its copier is resumed: what the master opened during a pause is never copied.
Pending orders
With copy_pending: false, the default, a master's pending order is copied when it fills, as a market order.
With copy_pending: true, each pending order the master places is placed on the follower too:
- It has the same type and price, and the master's stop loss and take profit. Its size follows the follower's rules. With
reverse, it is the opposite type at the same price, with the stops swapped: a buy limit becomes a sell stop. - When the master moves its order, the follower's order moves with it. When the master cancels its order, or the order expires, the follower's order is cancelled. The expiry time is copied too if the follower's broker accepts it. If not, the follower's order stays until the master's expires.
- When the follower's order fills, that position is the copy and follows the master from then on.
- If the master's order fills and the follower's hasn't filled within 2 seconds, the follower's order is cancelled and the copy opens at the market. If the follower's order fills just as it is being cancelled, the follower still ends up with exactly one copy of the trade.
- Orders the master already has when the follower is attached are left alone, unless
copy_existingis set. Orders the master places during a pause are never placed on the follower. If one fills after the pause, that fill is copied like any new trade.
Even with copy_pending, stop-limit orders are copied only when they fill if the follower is on MT4, which has no stop-limit orders, or uses reverse.
If you cancel a follower's pending order by hand, it stays cancelled. Turning copy_pending off cancels the follower's pending orders that were placed for the master's.
Symbols
symbol_filter and symbols choose which of the master's symbols are copied:
symbol_filter | Copies |
|---|---|
all | Every symbol. symbols is ignored |
include | Only the symbols in symbols |
exclude | Every symbol except those in symbols |
symbols holds the master's symbol names. A name also covers the same name with a broker's extra characters: XAUUSD also covers XAUUSD.m. With include or exclude, symbols can't be empty.
Matching
Brokers name the same instrument differently, so each master symbol is matched to one of the follower broker's symbols, in this order:
- The follower's own
symbol_map. - The same name.
- The same name without the broker's extra characters, such as
EURUSD.morUS30.cash. - Known aliases, such as
XAUUSDandGOLD.
When several symbols fit, the plain name wins: US500 over US500m. Anything still ambiguous is skipped, never guessed.
The full list of aliases, with examples, is on copying between MT4 and MT5.
Mapping
Map only the names that don't match by themselves:
{ "symbol_map": { "XAUUSD": "GOLD.pro", "NAS100": "USTEC" } }Keys are the master's symbol names, values the follower's. Each name is up to 32 characters.
Trading sessions
sessions limits when new trades are copied. Each session has the weekdays it applies to and a start and end time:
{
"sessions": [
{ "days": [0, 1, 2, 3, 4], "start": "07:00", "end": "16:30" },
{ "days": [6], "start": "22:00", "end": "02:00" }
],
"timezone": "Europe/London"
}daysare 0 (Monday) to 6 (Sunday).startandendareHH:MM, 24-hour. An end before its start runs past midnight, like the Sunday session above. A session can't start and end at the same time.- Up to 14 sessions. With none, trades are copied at any time.
- Sessions only decide which new trades are copied. Copies that are already open always follow the master's closes and stop loss or take profit changes, at any time.
timezone sets which clock the session times use. It is either broker, the master broker's server time as its MetaTrader charts show it, or a time zone name such as Europe/London or America/New_York.
The follower object
{
"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": "Funded #2",
"platform": "mt5",
"server": "ICMarketsSC-Demo",
"login": 51239876,
"status": "connected"
},
"is_active": true,
"magic": 1840273951,
"lot_mode": "multiplier",
"lot_value": 0.5,
"adjust_contract_size": true,
"below_minimum": "minimum",
"max_lot": 5,
"reverse": false,
"copy_stops": true,
"max_slippage_pips": null,
"max_delay_seconds": 60,
"copy_existing": false,
"copy_pending": false,
"symbol_filter": "all",
"symbols": [],
"sessions": [],
"timezone": "broker",
"symbol_map": {},
"status": {
"state": "copying",
"message": "",
"master_connected": true,
"follower_connected": true,
"open_copies": 2,
"last_event_at": "2026-10-25T14:21:07.430Z",
"balance": 5000.0,
"equity": 5031.2,
"currency": "USD",
"heartbeat_at": "2026-10-25T14:21:15.002Z",
"engine_online": true
},
"created_at": "2026-10-25T14:09:02.118Z",
"updated_at": "2026-10-25T14:09:02.118Z"
}| Field | Description |
|---|---|
id | The follower's ID, a UUID. It isn't the account's ID |
copier_id | The copier it belongs to |
account_id | The account that copies |
account | A summary of that account: id, name, platform, server, login and status |
is_active | false while it is paused |
magic | The magic number on every order the copier places for this follower |
| Rules | Every field of Rules |
status | The live status from the copier engine. null until the engine first reports on this follower |
created_at, updated_at | When it was attached and last changed |
Status
The copier engine refreshes status on every change, and at least every 15 seconds.
| Field | Description |
|---|---|
state | starting, copying, paused or error |
message | When state is error, what needs attention. Paused by Equity Guard. while Equity Guard holds copying back. Otherwise usually empty |
master_connected, follower_connected | Whether the engine is connected to each account's terminal |
open_copies | How many of this follower's copies are open |
last_event_at | When the engine last acted on this follower, or null |
balance, equity, currency | The follower's figures as the engine last saw them. null until they arrive |
heartbeat_at | When the engine last reported |
engine_online | false when the engine hasn't reported for 60 seconds. The rest of the status is then out of date |
List and read followers
GET /v1/copiers/{copier_id}/followers lists the copier's followers, oldest first, in the list format. GET /v1/copiers/{copier_id}/followers/{follower_id} returns one. Reading the copier itself returns all of them too.
Change a follower's rules
curl -X PATCH https://api.algotradertools.com/v1/copiers/c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f/followers/e2f4a6b8-c0d2-4e46-8a8c-9e0f1a2b3c4d \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "lot_value": 0.25, "symbol_map": { "XAUUSD": "GOLD.pro" } }'PATCH changes only the fields you send, and the engine picks up the change within seconds. Lists and objects are replaced as a whole: sending symbols or symbol_map replaces the previous value. The account can't be changed: sending account_id fails with the code immutable. To copy to another account, attach it as a new follower.
You can also send the whole follower back as you read it, with your changes. Read-only fields such as id, account, magic and status are ignored. A field that followers don't have, such as a misspelt lot_vlaue, is refused with validation_failed and the code unknown_field instead of being ignored.
Pause and resume a follower
curl -X PATCH https://api.algotradertools.com/v1/copiers/c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f/followers/e2f4a6b8-c0d2-4e46-8a8c-9e0f1a2b3c4d \
-H "Authorization: Bearer $ATT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'While a follower is paused, nothing new is copied to it. Copies that are already open stay open, and still follow the master's closes and changes. Resuming with "is_active": true copies from that moment on. What the master opened while the follower was paused stays uncopied, also with copy_existing.
Equity Guard can pause a follower too. That pause shows in the follower's status, not in is_active, and you resume it in the app.
Remove a follower
curl -X DELETE "https://api.algotradertools.com/v1/copiers/c7d1e5f2-3a4b-4c6d-8e9f-0a1b2c3d4e5f/followers/e2f4a6b8-c0d2-4e46-8a8c-9e0f1a2b3c4d?close_positions=true" \
-H "Authorization: Bearer $ATT_API_KEY"close_positions=true (or 1) closes the follower's copies at market before it is removed. Without it, or with false (0), they stay open as ordinary positions that the copier no longer manages. Any other value fails with validation_failed. If a terminal refuses to close them, the request fails with close_failed (502, 503 or 504). The follower is kept but paused, so nothing new is copied while you decide what to do.
When the removal succeeds, the response is 204 No Content. Removing a follower deletes its events. The account stays connected.