Update Monitor
Change one or more fields of a monitor. The change is validated as a whole before anything is saved.
The Management API requires an Elite subscription. See Authentication.
- NT8
- Tradovate
Endpoint
PATCH https://app.crosstrade.io/v1/api/manage/nt8/monitors/{account}
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
| If-Match | No | ETag from a previous read. The request fails with 412 if the monitor changed since then |
Path parameters
| Name | Type | Description |
|---|---|---|
account | string | Account name, URL-encoded (exact match, including case; no leading or trailing spaces) |
Body parameters
Send any writable field from Monitor fields. Leave out what you do not want to change. Nested objects merge; arrays such as tradingWindows replace the saved array.
Code examples
- Python
- cURL
import requests
resp = requests.patch(
"https://app.crosstrade.io/v1/api/manage/nt8/monitors/Sim101",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'dailyLossLimit': 400, 'autoFlattenTime': None},
)
print(resp.status_code, resp.json())
curl -X PATCH "https://app.crosstrade.io/v1/api/manage/nt8/monitors/Sim101" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dailyLossLimit": 400, "autoFlattenTime": null}'
Responses
- 200
- Other errors
{
"success": true,
"changed": true,
"data": {
"account": "Sim101",
"nickname": null,
"active": true,
"state": "active",
"stoppedReason": null,
"pnlMode": "standard",
"includeUnrealized": true,
"dailyProfitTarget": 1000,
"dailyLossLimit": 400,
"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": [
{
"enabled": true,
"start": "09:30",
"end": "15:45",
"flattenAtEnd": false
}
],
"newsLockout": {
"blockSignals": true,
"flatten": false
},
"blockSignals": false,
"closingOnly": false,
"switchesLocked": false,
"positionProfitTarget": 0,
"positionLossLimit": 0,
"includeCommissions": true,
"cleanSessionProtection": true,
"outlierProtection": {
"enabled": true,
"sensitivity": "low"
},
"created": "2026-09-01T13:02:11Z",
"updated": "2026-10-02T14:31:07Z"
},
"changedFields": [
"autoFlattenTime",
"dailyLossLimit"
],
"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 |
| 400 | invalid_path | The account name in the path is not valid |
| 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 |
| 404 | not_found | No monitor for this account on your login |
| 409 | monitor_stopped_use_restart | active: true on a stopped or inactive monitor |
| 409 | monitor_locked | Monitor Lock is holding this monitor until 5:00 PM ET |
| 409 | field_locked | A limit on this account is managed by another feature |
| 409 | switches_locked | blockSignals or closingOnly changed while switchesLocked is on. Send switchesLocked: false too |
| 409 | concurrent_modification | Another change to your monitors is in progress |
| 412 | precondition_failed | If-Match did not match |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | validation_failed | A field is invalid, or the change breaks a rule (for example unrealized mode without flatten) |
| 422 | field_read_only, immutable_field | A read-only field, or account, was sent with a value different from the saved one |
| 429 | rate_limited, too_many_concurrent_requests | See Rate limits |
| 503 | management_read_only, management_busy, storage_unavailable, outcome_unknown | See Errors |
Endpoint
PATCH https://app.crosstrade.io/v1/api/manage/tradovate/monitors/{account}
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
| If-Match | No | ETag from a previous read. The request fails with 412 if the monitor changed since then |
Path parameters
| Name | Type | Description |
|---|---|---|
account | string | Account name, URL-encoded (matched in any case; no leading or trailing spaces) |
Body parameters
Send any writable field from Monitor fields. Leave out what you do not want to change. Nested objects merge; arrays such as tradingWindows replace the saved array.
Code examples
- Python
- cURL
import requests
resp = requests.patch(
"https://app.crosstrade.io/v1/api/manage/tradovate/monitors/DEMO12345678",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'dailyLossLimit': 400, 'autoFlattenTime': None},
)
print(resp.status_code, resp.json())
curl -X PATCH "https://app.crosstrade.io/v1/api/manage/tradovate/monitors/DEMO12345678" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dailyLossLimit": 400, "autoFlattenTime": null}'
Responses
- 200
- 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": 400,
"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": [
{
"enabled": true,
"start": "09:30",
"end": "15:45",
"flattenAtEnd": false
}
],
"newsLockout": {
"blockSignals": true,
"flatten": false
},
"blockSignals": false,
"closingOnly": false,
"switchesLocked": false,
"created": "2026-09-01T13:02:11Z",
"updated": "2026-10-02T14:31:07Z"
},
"changedFields": [
"autoFlattenTime",
"dailyLossLimit"
],
"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 |
| 400 | invalid_path | The account name in the path is not valid |
| 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 |
| 404 | not_found | No monitor for this account on your login |
| 409 | monitor_stopped_use_restart | active: true on a stopped or inactive monitor |
| 409 | monitor_locked | Monitor Lock is holding this monitor until 5:00 PM ET |
| 409 | field_locked | A limit on this account is managed by another feature |
| 409 | switches_locked | blockSignals or closingOnly changed while switchesLocked is on. Send switchesLocked: false too |
| 409 | concurrent_modification | Another change to your monitors is in progress |
| 409 | tradovate_not_linked, account_identity_unresolved | The monitor is or would be on, and your Tradovate login is not linked or the account cannot be matched to it |
| 409 | limit_reached | You have the maximum number of active Tradovate monitors |
| 412 | precondition_failed | If-Match did not match |
| 413 | body_too_large | The body is larger than 64 KB |
| 415 | unsupported_content_type | The body is not application/json |
| 422 | validation_failed | A field is invalid, or the change breaks a rule (for example unrealized mode without flatten) |
| 422 | field_read_only, immutable_field | A read-only field, or account, was sent with a value different from the saved one |
| 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. Auto-flatten and flatten at the end of a trading window run on weekdays, for monitors that are active.
Notes
- To pause a monitor send
{"active": false}. To resume a stopped monitor use Restart Monitor:active: trueis refused while it is stopped. nullclearsnickname,accountFloorandautoFlattenTime."tradingWindows": []removes every window.- You can send back a whole monitor from a
GET. Read-only fields that match the saved values are ignored,updatedis always ignored, and the response ischanged: falsewhen nothing differs. On a stopped or inactive monitor an echoedactive: trueis accepted as unchanged with amonitor_stopped_use_restartwarning; use restart to resume it. - Times you send (
autoFlattenTime,tradingWindows[].startandend) must be on a 5-minute mark. - A value saved before today's rules does not block other changes, and the fields you do not send are not rewritten.
- A save in the web app right after an API change can overwrite it, because the web editor sends the whole monitor.
If-Matchprotects against other API clients only.