GET Order Lifecycle
Requires CrossTrade XT Add-On v1.13.2 or later. Older add-ons return an "Unknown API command" error. Update from the XT Versions changelog.
Get order lifecycle by ID
GET /v1/api/accounts/{account}/orders/{orderId}/lifecycle
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.
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 | integer | 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
- 404
- 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"
}
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
}
}