Skip to main content

GET Order Lifecycle

Available in v1.13.2

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

NameValue
Content-Typeapplication/json
AuthorizationBearer <token>

Path Parameters

NameTypeRequiredDescription
accountstringRequiredRequired 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.
orderIdstringRequiredNT8 OrderId or the original/xt id supplied at placement time. Either resolves correctly.

Query Parameters

NameTypeRequiredDescription
includeFillsbooleanOptionalDefault true. Merge fill events from NT8's in-memory Executions into the timeline.
includeRawbooleanOptionalDefault false. Include the full raw JSON snapshot for each event (verbose).
limitintegerOptionalDefault 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

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}")

Response

{
"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
}
]
}

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). The reason field carries the error string.
  • order_update: NT8 fired its Account.OrderUpdate event. The orderState field 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 when includeFills=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
}
}