GET Order Lifecycle
- NT8
- Tradovate
Get order lifecycle by ID NT8
Returns the complete lifecycle of a single order: every state transition recorded by the add-on (Submitted, Accepted, Working, PartFilled, Filled, Cancelled, Rejected, and so on), plus every inbound API submission attempt against the order, optionally merged with fills from NT8's in-memory Executions collection. Use this endpoint to reconcile orders end-to-end when a real-time WebSocket event was dropped, arrived out of order, or never made it to your application.
The add-on persists each event to its local SQLite the moment it happens, so the lifecycle is durable even across WebSocket disconnects or transient network failures. Default retention is 90 days.
Endpoint
GET /v1/api/accounts/{account}/orders/{orderId}/lifecycle
Headers
| Name | Value |
|---|---|
| Content-Type | application/json |
| Authorization | Bearer <token> |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Required | Required by the URL pattern. The add-on does not filter by account, so any name (e.g. Sim101) resolves the same lifecycle. Included for routing symmetry with the other per-order endpoints. |
orderId | string | Required | NT8 OrderId or the original/xt id supplied at placement time. Either resolves correctly. |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
includeFills | boolean | Optional | Default true. Merge fill events from NT8's in-memory Executions into the timeline. |
includeRaw | boolean | Optional | Default false. Include the full raw JSON snapshot for each event (verbose). |
limit | int | Optional | Default 200. Cap on rows returned. Server enforces a hard ceiling of 2000. If SQLite already returns limit rows, no fills will be merged. Bump limit if a single order has many lifecycle events and fills are needed. |
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/accounts/Sim101/orders/50cca7b8051146c684087db511107983/lifecycle"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
params = {
"includeFills": True,
"limit": 200
}
try:
response = requests.get(url, headers=headers, params=params)
print(f"Response Code: {response.status_code}, Response Text: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")
const token = 'my-secret-token';
const params = new URLSearchParams({ includeFills: "true", limit: "200" });
const url = `https://app.crosstrade.io/v1/api/accounts/Sim101/orders/50cca7b8051146c684087db511107983/lifecycle?${params}`;
fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
TOKEN="my-secret-token"
curl -X GET "https://app.crosstrade.io/v1/api/accounts/Sim101/orders/50cca7b8051146c684087db511107983/lifecycle?includeFills=true&limit=200" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json"
Response
- 200
- 400 - not found
- 400
{
"success": true,
"orderId": "50cca7b8051146c684087db511107983",
"originalOrderId": "myStrat_entry_42",
"account": "Sim101",
"count": 5,
"events": [
{
"timestamp": "2026-05-22T14:30:12.118Z",
"epoch": 1779114612118.0,
"source": "api_received",
"event": "PlaceOrder",
"orderState": null,
"account": "Sim101",
"orderId": "myStrat_entry_42",
"originalOrderId": null,
"correlationId": null,
"filled": null,
"quantity": 1,
"avgFillPrice": null,
"limitPrice": 5235.00,
"stopPrice": null,
"reason": null
},
{
"timestamp": "2026-05-22T14:30:12.214Z",
"epoch": 1779114612214.0,
"source": "order_update",
"event": "Submitted",
"orderState": "Submitted",
"account": "Sim101",
"orderId": "50cca7b8051146c684087db511107983",
"originalOrderId": "myStrat_entry_42",
"correlationId": null,
"filled": 0,
"quantity": 1,
"avgFillPrice": 0.0,
"limitPrice": 5235.00,
"stopPrice": 0.0,
"reason": null
},
{
"timestamp": "2026-05-22T14:30:12.241Z",
"epoch": 1779114612241.0,
"source": "order_update",
"event": "Working",
"orderState": "Working",
"account": "Sim101",
"orderId": "50cca7b8051146c684087db511107983",
"originalOrderId": "myStrat_entry_42",
"correlationId": null,
"filled": 0,
"quantity": 1,
"avgFillPrice": 0.0,
"limitPrice": 5235.00,
"stopPrice": 0.0,
"reason": null
},
{
"timestamp": "2026-05-22T14:31:48.902Z",
"epoch": 1779114708902.0,
"source": "execution",
"event": "Execution",
"orderState": null,
"account": "Sim101",
"orderId": "50cca7b8051146c684087db511107983",
"originalOrderId": "myStrat_entry_42",
"correlationId": null,
"executionId": "abc-exec-1",
"filled": 1,
"quantity": null,
"avgFillPrice": 5235.00,
"limitPrice": null,
"stopPrice": null,
"reason": null
},
{
"timestamp": "2026-05-22T14:31:48.911Z",
"epoch": 1779114708911.0,
"source": "order_update",
"event": "Filled",
"orderState": "Filled",
"account": "Sim101",
"orderId": "50cca7b8051146c684087db511107983",
"originalOrderId": "myStrat_entry_42",
"correlationId": null,
"filled": 1,
"quantity": 1,
"avgFillPrice": 5235.00,
"limitPrice": 5235.00,
"stopPrice": 0.0,
"reason": null
}
]
}
{
"success": false,
"error": "not_found",
"detail": "No lifecycle events found for orderId '50cca7b8051146c684087db511107983'. The order may pre-date v1.13.2 or may not exist on this machine."
}
{
"success": false,
"error": "missing_args",
"detail": "'orderId' is required"
}
Platform nuances
Requires CrossTrade NT8 Add-On v1.13.2 or later. Older add-ons return an "Unknown API command" error. Update from the Add-On Changelog.
Source field
The source column tells you which side of the system emitted the event:
api_received: the add-on accepted an inbound order-mutation API call (PlaceOrder, Cancel, Change, and so on). Captured before the call reaches NT8.api_rejected: the add-on rejected the call before it reached NT8 (validation, missing account, malformed args). Thereasonfield carries the error string.order_update: NT8 fired itsAccount.OrderUpdateevent. TheorderStatefield carries the NT8 state string (Submitted,Working,PartFilled,Filled,Cancelled,Rejected,Expired, etc.).execution: synthesized at read time from NT8's in-memory Executions. Only present whenincludeFills=true.
WebSocket API
This request can also be made over the WebSocket API. Only orderId is required; account and the query parameters are accepted but optional (the add-on does not filter by account).
{
"action": "rpc",
"id": "my-request-id",
"api": "GetOrderLifecycle",
"args": {
"orderId": "50cca7b8051146c684087db511107983",
"includeFills": true
}
}
Get order lifecycle by ID Tradovate
Returns the Tradovate audit trail for one order. No NinjaTrader add-on is involved: the trail is assembled server-side from Tradovate's order, orderVersion, command, and commandReport dependency reads, so it works while NinjaTrader is closed and does not require NT8 Add-On v1.13.2.
Endpoint
GET /v1/api/tv/accounts/{account}/orders/{id}/lifecycle
Headers
| Name | Value |
|---|---|
| Content-Type | application/json |
| Authorization | Bearer <token> |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Required | Tradovate account name, for example DEMO12345678. |
id | string | Required | Tradovate order id, for example 123456789. |
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/123456789/lifecycle"
headers = {
"Authorization": f"Bearer {token}"
}
try:
response = requests.get(url, headers=headers)
print(f"Response Code: {response.status_code}, Response Text: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")
const token = 'my-secret-token';
const url = "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/123456789/lifecycle";
fetch(url, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`
}
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
TOKEN="my-secret-token"
curl -X GET "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/orders/123456789/lifecycle" \
-H "Authorization: Bearer $TOKEN"
Response
The response uses the Tradovate read envelope. data contains the current order, its latest version, related commands, and reports.
{
"success": true,
"data": {
"order": {},
"version": {},
"commands": [],
"reports": []
}
}
Platform nuances
- Unlike the NT8 endpoint, there are no
includeFills,includeRaw, orlimitquery parameters. - Report rows carry
rejectReasonand human-readabletextfor refused commands. - Reports are capped to those associated with the last 10 commands.
- Fills are not merged into this response. Retrieve them separately from
GET /v1/api/tv/fills/order/{orderId}. - Tradovate uses
{id}for this route; the separate fills route retains{orderId}. {account}remains a required path segment; the current lifecycle read resolves the order by its Tradovate order id.
See the Tradovate API overview for the full route list and error table.