Create Copier
Create a trade copier. The response is 201 Created with a Location header that points at the new copier.
New copiers start off
A copier created without "active": true does not copy anything until you turn it on.
Elite
The Management API requires an Elite subscription. See Authentication.
- NT8
- Tradovate
Endpoint
POST https://app.crosstrade.io/v1/api/manage/nt8/copiers
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
type | single or group | Yes | One follower, or a named group |
leader | string | Yes | The account to copy |
followers | array of {account, ratio?} | Yes | Exactly 1 for single; 2 to 200 for group |
groupName | string | For group | Name of the group |
| any other writable field | see Copier fields | No | Left out, a field takes the web app default. active defaults to false |
Code examples
- Python
- cURL
import requests
resp = requests.post(
"https://app.crosstrade.io/v1/api/manage/nt8/copiers",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'type': 'single', 'leader': 'Sim101', 'followers': [{'account': 'DemoAccount'}], 'instruments': ['ES', 'NQ'], 'active': True},
)
print(resp.status_code, resp.json())
curl -X POST "https://app.crosstrade.io/v1/api/manage/nt8/copiers" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "single", "leader": "Sim101", "followers": [{"account": "DemoAccount"}], "instruments": ["ES", "NQ"], "active": true}'
Responses
- 201
- Other errors
{
"success": true,
"changed": true,
"data": {
"id": "4b1f0c9e2d7a4c55b1e0",
"nickname": null,
"active": true,
"mode": "order",
"leader": "Sim101",
"type": "single",
"groupName": null,
"followers": [
{
"account": "DemoAccount"
}
],
"sizing": {
"method": "ratio",
"ratio": 1,
"quantity": null,
"maxQuantity": null
},
"inverse": false,
"fillsOnly": false,
"instruments": [
"ES",
"NQ"
],
"symbolReplacements": {},
"stealth": true,
"tandem": false,
"autoSync": {
"enabled": true,
"intervalSeconds": 10
},
"syncCorrection": {
"cooldownSeconds": 300,
"maxAttempts": 1
},
"reconnectDelayMs": 10000,
"strategyTagMode": "override",
"created": "2026-10-02T14:31:07Z",
"updated": "2026-10-02T14:31:07Z"
},
"changedFields": [
"active",
"autoSync.enabled",
"autoSync.intervalSeconds",
"fillsOnly",
"followers",
"id",
"instruments",
"inverse",
"leader",
"mode",
"reconnectDelayMs",
"sizing.method",
"sizing.ratio",
"stealth",
"strategyTagMode",
"syncCorrection.cooldownSeconds",
"syncCorrection.maxAttempts",
"tandem",
"type"
],
"delivery": {
"status": "queued",
"target": "nt8_addon"
},
"warnings": [],
"meta": {
"requestId": "req_9f2c1a0b7d3e4f51",
"etag": "\"c2:Tm90UmVhbEV0YWcwMg\""
}
}
| Status | error | When |
|---|---|---|
| 400 | invalid_json | The body is not valid JSON |
| 401 | unauthorized | Missing or invalid token |
| 403 | elite_required, not_available | See Authentication |
| 404 | account_not_found | An account is not on your NinjaTrader connection (Backtest and Playback101 are never accepted) |
| 409 | addon_disconnected | The add-on is not connected, so the accounts cannot be checked |
| 409 | addon_version_unsupported | Sharing a follower between copiers needs add-on v1.10.10 or newer |
| 409 | autosync_conflict | A shared follower would have overlapping instruments with Auto-Sync on |
| 409 | concurrent_modification | Another change to your copiers is in progress |
| 409 | copier_cycle | The copier would create a copy loop |
| 409 | duplicate_copier | A copier on the same leader and follower already covers these instruments |
| 409 | group_name_conflict | The group name matches one of your account names |
| 409 | tandem_requires_monitor | Tandem is on and a follower has no monitor |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | field_read_only, field_not_applicable | A read-only field (id, created, updated, followers[].environment), or a field this broker does not have, was sent |
| 422 | invalid_replacement | A symbol replacement is not allowed |
| 422 | validation_failed | A field is invalid, or the combination breaks a rule (for example fillsOnly in execution mode, or a ratio that is not one of the allowed steps, code ratio_not_a_step) |
| 429 | rate_limited, too_many_concurrent_requests | See Rate limits |
| 503 | management_read_only, management_busy, storage_unavailable, outcome_unknown | See Errors |
Endpoint
POST https://app.crosstrade.io/v1/api/manage/tradovate/copiers
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
type | single or group | Yes | One follower, or a named group |
leader | string | Yes | The account to copy |
followers | array of {account, ratio?} | Yes | Exactly 1 for single; 2 to 200 for group |
groupName | string | For group | Name of the group |
| any other writable field | see Copier fields | No | Left out, a field takes the web app default. active defaults to false |
Code examples
- Python
- cURL
import requests
resp = requests.post(
"https://app.crosstrade.io/v1/api/manage/tradovate/copiers",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'type': 'single', 'leader': 'DEMO12345678', 'followers': [{'account': 'DEMO87654321'}], 'instruments': ['ES', 'NQ'], 'active': True},
)
print(resp.status_code, resp.json())
curl -X POST "https://app.crosstrade.io/v1/api/manage/tradovate/copiers" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"type": "single", "leader": "DEMO12345678", "followers": [{"account": "DEMO87654321"}], "instruments": ["ES", "NQ"], "active": true}'
Responses
- 201
- Other errors
{
"success": true,
"changed": true,
"data": {
"id": "9c3e5a7b1d2f4e6a8b0c",
"nickname": null,
"active": true,
"mode": "signal",
"leader": "DEMO12345678",
"type": "single",
"groupName": null,
"followers": [
{
"account": "DEMO87654321",
"environment": "demo"
}
],
"sizing": {
"method": "ratio",
"ratio": 1,
"quantity": null,
"maxQuantity": null
},
"inverse": false,
"fillsOnly": false,
"instruments": [
"ES",
"NQ"
],
"symbolReplacements": {},
"stealth": true,
"tandem": false,
"autoSync": {
"enabled": true
},
"syncCorrection": {
"cooldownSeconds": 300,
"maxAttempts": 1
},
"created": "2026-10-02T14:31:07Z",
"updated": "2026-10-02T14:31:07Z"
},
"changedFields": [
"active",
"autoSync.enabled",
"fillsOnly",
"followers",
"id",
"instruments",
"inverse",
"leader",
"mode",
"sizing.method",
"sizing.ratio",
"stealth",
"syncCorrection.cooldownSeconds",
"syncCorrection.maxAttempts",
"tandem",
"type"
],
"delivery": {
"status": "automatic",
"target": "tradovate_engine"
},
"warnings": [],
"meta": {
"requestId": "req_9f2c1a0b7d3e4f51",
"etag": "\"c2:Tm90UmVhbEV0YWcwMg\""
}
}
| Status | error | When |
|---|---|---|
| 400 | invalid_json | The body is not valid JSON |
| 401 | unauthorized | Missing or invalid token |
| 403 | elite_required, not_available | See Authentication |
| 403 | plan_required | The copier is on and your plan does not include the Tradovate copier |
| 404 | account_not_found | An account is not among your synced Tradovate accounts |
| 409 | account_identity_unresolved | An account could not be matched to your linked Tradovate login |
| 409 | concurrent_modification | Another change to your copiers is in progress |
| 409 | copier_cycle | The copier would create a copy loop |
| 409 | duplicate_copier | A copier on the same leader and follower already covers these instruments. With "active": true, any other copier on that pair |
| 409 | follower_conflict, duplicate_follower | A follower is already copied by another active copier and one of the two uses Auto-Sync, or a follower is listed twice |
| 409 | limit_reached | The leader has the maximum number of active followers |
| 409 | tandem_requires_monitor | Tandem is on and a follower has no monitor |
| 409 | tradovate_not_linked | The copier is on and no Tradovate login is linked |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | field_read_only, field_not_applicable | A read-only field (id, created, updated, followers[].environment), or a field this broker does not have, was sent |
| 422 | invalid_replacement | A symbol replacement is not allowed |
| 422 | validation_failed | A field is invalid, or the combination breaks a rule (for example fillsOnly in execution mode, or a ratio that is not one of the allowed steps, code ratio_not_a_step) |
| 429 | rate_limited, too_many_concurrent_requests | See Rate limits |
| 503 | management_read_only, management_busy, storage_unavailable, outcome_unknown | See Errors |
When it takes effect
NinjaTrader: sent to the add-on right after the save, or when it next connects. Tradovate: signal mode on the next signal, execution and order mode on the next fill.
Notes
- The copy-loop and duplicate checks compare against all your copiers, including ones that are off.
- A second copier on the same leader and follower is allowed only when the two copy different instruments. On Tradovate, a copier created with
"active": trueis refused when any other copier already links that leader and follower, whatever the instruments. tandem: trueneeds an Account Manager monitor on every follower (409 tandem_requires_monitor).- A NinjaTrader create checks the accounts with your add-on, so it needs the add-on connected (
409 addon_disconnected). - NinjaTrader copiers use ratio sizing only.
- There is no idempotency key, but retrying the same create is refused with
409 duplicate_copier, even when the first copier is off, because it already links that leader and follower on the same instruments. If a create response was lost, list your copiers to find it.