Create ATM Template
Create an ATM template. The response is 201 Created with a Location header. Config values use the webhook syntax described in Tradovate ATM.
Elite
The Management API requires an Elite subscription. See Authentication.
Endpoint
POST https://app.crosstrade.io/v1/api/manage/tradovate/atm-templates
Headers
| Name | Required | Value |
|---|---|---|
| Authorization | Yes | Bearer <your API token> |
| Content-Type | Yes | application/json |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Yes | The name webhooks use |
config | object | Yes | At least config.targets and config.stops |
description | string or null | No | Your note |
active | boolean | No | Defaults to false |
Code examples
- Python
- cURL
import requests
resp = requests.post(
"https://app.crosstrade.io/v1/api/manage/tradovate/atm-templates",
headers={"Authorization": "Bearer YOUR_TOKEN"},
json={'name': 'Scalp', 'description': 'Two targets, trail the runner', 'active': True,
'config': {'targets': '20,40', 'stops': '16,16', 'quantities': '1,1', 'trail': 'false,true'}},
)
print(resp.status_code, resp.json())
curl -X POST "https://app.crosstrade.io/v1/api/manage/tradovate/atm-templates" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Scalp", "description": "Two targets, trail the runner", "active": true, "config": {"targets": "20,40", "stops": "16,16", "quantities": "1,1", "trail": "false,true"}}'
Responses
- 201
- Other errors
{
"success": true,
"changed": true,
"data": {
"id": "tvatm_Qw12er34Ty56ui78",
"name": "Scalp",
"description": "Two targets, trail the runner",
"active": true,
"config": {
"targets": "20,40",
"stops": "16,16",
"quantities": "1,1",
"trail": "false,true",
"trailTrigger": null,
"trailOffset": null,
"breakeven": null,
"breakevenOffset": null
},
"created": "2026-10-02T14:31:07Z",
"updated": "2026-10-02T14:31:07Z"
},
"changedFields": [
"active",
"config.quantities",
"config.stops",
"config.targets",
"config.trail",
"description",
"name"
],
"delivery": {
"status": "immediate",
"target": "signal_gate"
},
"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 |
| 409 | concurrent_modification | Another change to your templates is in progress |
| 409 | template_name_conflict | Another template has this name |
| 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 | A read-only field (id, created, updated) was sent |
| 422 | invalid_atm_config | The configuration is not valid. detail names the problem and fields lists the config.* fields involved |
| 422 | validation_failed | A field is invalid |
| 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
The next webhook signal that names the template.
Notes
- New templates are off unless you send
"active": true. Webhooks can only use active templates. - Names are unique without regard to case, so a retried create is refused with
409 template_name_conflictand cannot make a second template. - An invalid configuration returns
422 invalid_atm_configwith adetailsuch asconfig.quantities must have exactly 2 value(s) to match config.targets; got 1andfieldsnamingconfig.quantitiesandconfig.targets.