PATCH Controls
Update one or more global controls. Send only the fields you want to change.
The Management API requires an Elite subscription. See Authentication.
Endpoint
PATCH https://app.crosstrade.io/v1/api/manage/controls
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 controls changed since then. |
Body parameters
| Name | Type | Required | Constraints | Description |
|---|---|---|---|---|
closingOnly | boolean | No | Block opening signals on every account | |
tradingWindow.days | array of sun mon tue wed thu fri sat | No | Unique. Empty array turns the window off | Days signals are accepted |
tradingWindow.start | string HH:MM or null | No | A 5-minute mark. Required when days is not empty | Window start, New York time |
tradingWindow.end | string HH:MM or null | No | A 5-minute mark, different from start. Required when days is not empty. Earlier than start means the window runs past midnight | Window end, New York time |
tradingWindow.closingOnlyAfter | string HH:MM or null | No | A 5-minute mark strictly inside the window; null turns it off | From this time until end, only closing signals are accepted |
monitorLock | boolean | No | Monitor Lock. Turning it off releases every locked monitor right away | |
enhancedClosingOnly | boolean | No | NinjaTrader only | Enforce each monitor's Closing Only inside the add-on |
Every field is optional, but the result must be valid as a whole: for example, sending tradingWindow.days while no start or end is saved fails with required_when_days_set. The checks that end differs from start and that closingOnlyAfter falls inside the window apply even while days is empty, because saved times take effect as soon as you add a day. Field details are in the Controls field reference.
killSwitch cannot be changed here. Use PUT Kill Switch. You can still send back the whole object from GET Controls: a killSwitch equal to the saved value is ignored.
Code examples
- Python
- JavaScript
- cURL
import requests
resp = requests.patch(
"https://app.crosstrade.io/v1/api/manage/controls",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={"tradingWindow": {"days": ["mon", "tue", "wed", "thu", "fri"],
"start": "09:30", "end": "15:55"}},
)
print(resp.status_code, resp.json())
const resp = await fetch("https://app.crosstrade.io/v1/api/manage/controls", {
method: "PATCH",
headers: { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json" },
body: JSON.stringify({ closingOnly: true }),
});
console.log(resp.status, await resp.json());
curl -X PATCH https://app.crosstrade.io/v1/api/manage/controls \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"closingOnly": true}'
Responses
- 200
- 422
- Other errors
{
"success": true,
"changed": true,
"data": {
"killSwitch": false,
"closingOnly": true,
"tradingWindow": { "days": [], "start": "09:30", "end": "16:00", "closingOnlyAfter": null },
"monitorLock": false,
"enhancedClosingOnly": false
},
"changedFields": ["closingOnly"],
"delivery": { "status": "immediate", "target": "signal_gate" },
"warnings": [],
"meta": { "requestId": "req_9f2c1a0b7d3e4f51", "etag": "\"c2:Tm90UmVhbEV0YWcwMg\"" }
}
{
"success": false,
"error": "validation_failed",
"detail": "One or more fields are invalid.",
"fields": [ { "path": "tradingWindow.start", "code": "required_when_days_set" } ],
"meta": { "requestId": "req_0c6a1d2e3f405162" }
}
| Status | error | When |
|---|---|---|
| 400 | invalid_json | The body is not valid JSON |
| 401 | unauthorized | Missing or invalid token |
| 403 | elite_required | Your plan is not Elite |
| 403 | not_available | The Management API is not open for your account yet |
| 409 | concurrent_modification | Another change to your controls 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: a time not on a 5-minute mark, start equal to end (empty_window), or closingOnlyAfter outside the window (outside_window) |
| 422 | use_kill_switch_endpoint | Body contains a killSwitch different from the saved one |
| 429 | rate_limited, too_many_concurrent_requests | See Rate limits |
| 503 | management_read_only, management_busy, storage_unavailable | See Errors |
When it takes effect
closingOnly and the trading window apply to the next incoming webhook signal. They do not affect orders you place through the trading API or directly in your platform. monitorLock is checked the next time a monitor is saved, restarted or deleted. enhancedClosingOnly is sent to the add-on right away, or when it next connects. See Effect timing.
Notes
- Sending the same values that are already saved returns
changed: falseand saves nothing. - The trading window days are case-sensitive on the wire: use lowercase
mon,tue, and so on.