Create Monitor
Create a monitor for an account. Only account is required. The response is 201 Created with a Location header that points at the new monitor.
Elite
The Management API requires an Elite subscription. See Authentication.
- NT8
- Tradovate
Endpoint
POST https://app.crosstrade.io/v1/api/manage/nt8/monitors
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Yes | The account to protect, exactly as NinjaTrader names it (case matters) |
| any writable field | see Monitor fields | No | Left out, a field takes the web app default |
Code examples
- Python
- cURL
import requests
resp = requests.post(
"https://app.crosstrade.io/v1/api/manage/nt8/monitors",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'account': 'Sim101', 'dailyLossLimit': 500, 'dailyProfitTarget': 1000, 'active': True},
)
print(resp.status_code, resp.json())
curl -X POST "https://app.crosstrade.io/v1/api/manage/nt8/monitors" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"account": "Sim101", "dailyLossLimit": 500, "dailyProfitTarget": 1000, "active": true}'
Responses
- 201
- Other errors
{
"success": true,
"changed": true,
"data": {
"account": "Sim101",
"nickname": null,
"active": true,
"state": "active",
"stoppedReason": null,
"pnlMode": "standard",
"includeUnrealized": true,
"dailyProfitTarget": 1000,
"dailyLossLimit": 500,
"onProfitTarget": {
"flatten": true,
"signals": "block"
},
"onLossLimit": {
"flatten": true,
"signals": "block"
},
"minimumProfit": {
"enabled": false,
"trigger": 0,
"threshold": 0,
"flatten": true,
"signals": "block"
},
"trailingDrawdown": {
"enabled": false,
"basis": "pnl",
"amount": 0,
"unit": "percent",
"trigger": 0,
"flatten": true,
"signals": "block"
},
"accountFloor": null,
"autoFlattenTime": null,
"tradingWindows": [],
"newsLockout": {
"blockSignals": false,
"flatten": false
},
"blockSignals": false,
"closingOnly": false,
"switchesLocked": false,
"positionProfitTarget": 0,
"positionLossLimit": 0,
"includeCommissions": true,
"cleanSessionProtection": true,
"outlierProtection": {
"enabled": true,
"sensitivity": "low"
},
"created": "2026-10-05T14:31:07Z",
"updated": "2026-10-05T14:31:07Z"
},
"changedFields": [
"account",
"active",
"blockSignals",
"cleanSessionProtection",
"closingOnly",
"dailyLossLimit",
"dailyProfitTarget",
"includeCommissions",
"includeUnrealized",
"minimumProfit.enabled",
"minimumProfit.flatten",
"minimumProfit.signals",
"minimumProfit.threshold",
"minimumProfit.trigger",
"newsLockout.blockSignals",
"newsLockout.flatten",
"onLossLimit.flatten",
"onLossLimit.signals",
"onProfitTarget.flatten",
"onProfitTarget.signals",
"outlierProtection.enabled",
"outlierProtection.sensitivity",
"pnlMode",
"positionLossLimit",
"positionProfitTarget",
"switchesLocked",
"tradingWindows",
"trailingDrawdown.amount",
"trailingDrawdown.basis",
"trailingDrawdown.enabled",
"trailingDrawdown.flatten",
"trailingDrawdown.signals",
"trailingDrawdown.trigger",
"trailingDrawdown.unit"
],
"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 |
| 403 | plan_required | Your plan does not include a feature you turned on (for example the news rules) |
| 404 | account_not_found | Your connected add-on does not list this account (Backtest and Playback101 are never accepted) |
| 409 | already_exists | This account already has a monitor |
| 409 | concurrent_modification | Another change to your monitors is in progress |
| 409 | addon_disconnected | The add-on is not connected, so the account cannot be checked |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | validation_failed, field_read_only | A field is invalid, or read-only (for example state or environment) |
| 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/monitors
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Yes | The Tradovate account to protect (any case) |
| any writable field | see Monitor fields | No | Left out, a field takes the web app default |
Code examples
- Python
- cURL
import requests
resp = requests.post(
"https://app.crosstrade.io/v1/api/manage/tradovate/monitors",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'account': 'DEMO12345678', 'dailyLossLimit': 500, 'dailyProfitTarget': 1000, 'active': True},
)
print(resp.status_code, resp.json())
curl -X POST "https://app.crosstrade.io/v1/api/manage/tradovate/monitors" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"account": "DEMO12345678", "dailyLossLimit": 500, "dailyProfitTarget": 1000, "active": true}'
Responses
- 201
- Other errors
{
"success": true,
"changed": true,
"data": {
"account": "DEMO12345678",
"environment": "demo",
"nickname": null,
"active": true,
"state": "active",
"stoppedReason": null,
"pnlMode": "standard",
"includeUnrealized": true,
"dailyProfitTarget": 1000,
"dailyLossLimit": 500,
"onProfitTarget": {
"flatten": true,
"signals": "block"
},
"onLossLimit": {
"flatten": true,
"signals": "block"
},
"minimumProfit": {
"enabled": false,
"trigger": 0,
"threshold": 0,
"flatten": true,
"signals": "block"
},
"trailingDrawdown": {
"enabled": false,
"basis": "pnl",
"amount": 0,
"unit": "dollars",
"trigger": 0,
"flatten": true,
"signals": "block"
},
"accountFloor": null,
"autoFlattenTime": null,
"tradingWindows": [],
"newsLockout": {
"blockSignals": false,
"flatten": false
},
"blockSignals": false,
"closingOnly": false,
"switchesLocked": false,
"created": "2026-10-05T14:31:07Z",
"updated": "2026-10-05T14:31:07Z"
},
"changedFields": [
"account",
"active",
"blockSignals",
"closingOnly",
"dailyLossLimit",
"dailyProfitTarget",
"includeUnrealized",
"minimumProfit.enabled",
"minimumProfit.flatten",
"minimumProfit.signals",
"minimumProfit.threshold",
"minimumProfit.trigger",
"newsLockout.blockSignals",
"newsLockout.flatten",
"onLossLimit.flatten",
"onLossLimit.signals",
"onProfitTarget.flatten",
"onProfitTarget.signals",
"pnlMode",
"switchesLocked",
"tradingWindows",
"trailingDrawdown.amount",
"trailingDrawdown.basis",
"trailingDrawdown.enabled",
"trailingDrawdown.flatten",
"trailingDrawdown.signals",
"trailingDrawdown.trigger",
"trailingDrawdown.unit"
],
"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 | Your plan does not include a feature you turned on (for example the news rules) |
| 404 | account_not_found | The account was not found on your linked Tradovate login |
| 409 | already_exists | This account already has a monitor, including one saved under a different spelling |
| 409 | concurrent_modification | Another change to your monitors is in progress |
| 409 | account_identity_unresolved, tradovate_not_linked | The account could not be matched to your linked Tradovate login |
| 409 | limit_reached | You have the maximum number of active Tradovate monitors |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | validation_failed, field_read_only | A field is invalid, or read-only (for example state or environment) |
| 422 | field_not_applicable | A NinjaTrader-only field was sent |
| 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: within about 10 seconds.
Notes
- New monitors are paused (
active: false) unless you sendactive: true. - The account must be yours. On NinjaTrader your add-on must be connected and list the account;
BacktestandPlayback101are never accepted. On Tradovate the account is matched against your linked Tradovate login. accountmay contain inner spaces. Leading or trailing spaces, tabs and other whitespace are refused with422 validation_failed.- A create costs 2 units of your change budget (20 per minute, burst 10), so about 5 creates go through at once and then one every 6 seconds. Creates do not count toward the per-resource budget. See Rate limits.
- If the response was lost, read the monitor before you retry: a second create for the same account returns
409 already_exists.