> ## Documentation Index
> Fetch the complete documentation index at: https://docs.engine.usesophic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Lifecycle

> How orders move from placement to settlement or cancellation

Every order moves through a defined set of statuses. Understanding this lifecycle helps you track orders correctly and handle all possible outcomes.

## Statuses

| Status      | Description                                                                                                 |
| ----------- | ----------------------------------------------------------------------------------------------------------- |
| `placed`    | We've accepted the order and validated it. It's queued for execution.                                       |
| `pending`   | The order is waiting on a prerequisite before it can be submitted (e.g. a price feed or a pre-trade check). |
| `executing` | The order has been submitted for execution.                                                                 |
| `filled`    | The order has been fully executed. Trades have been recorded.                                               |
| `settled`   | All trades for this order have been settled. Cash and positions reflect the final state.                    |
| `cancelled` | The order was cancelled and won't be executed.                                                              |

## State transitions

```
placed → pending → executing → filled → settled
   │         │          │
   └─────────┴──────────┴──→ cancelled
```

The typical happy path is `placed` → `pending` → `executing` → `filled` → `settled`. Not every order passes through `pending`; if no prerequisites need to be resolved, the order can move directly from `placed` to `executing`.

An order can be cancelled from `placed`, `pending`, or `executing`, but not after it's been `filled`.

## How an order reaches `settled`

<Steps>
  <Step title="You place the order">
    You send a `POST` request with the instrument, side, and either `cash_amount` (buy) or `quantity` (sell). We validate the request, check that the instrument is tradable, verify the account has sufficient funds or units, reserve the cash or units, and submit the order for execution. The order starts at `placed`.
  </Step>

  <Step title="The order becomes pending (sometimes)">
    If the order is waiting on a prerequisite (for example, a price feed update or a pre-trade compliance check) it moves to `pending`. Many orders skip this step entirely.
  </Step>

  <Step title="The order starts executing">
    Once submitted to our execution infrastructure, the order moves to `executing`. At this point, the order is actively being worked.
  </Step>

  <Step title="The order fills">
    When execution completes, the order moves to `filled`. Trades are recorded against the order, and the `traded_quantity` and `traded_notional` fields are updated. For buy orders, a position is created or increased. For sell orders, the position decreases.
  </Step>

  <Step title="The order settles">
    After all trades settle, the order moves to `settled`. This is the final resting state for a successful order. The account's cash balances and positions reflect the settled amounts.
  </Step>
</Steps>

## How an order gets cancelled

An order can be cancelled at any point before it fills:

* **By the system**: We'll cancel an order if validation fails during processing (e.g. the instrument stops trading, or the account is suspended), or if execution fails for a reason that can't be retried.
* **During execution**: If the order is `executing`, cancellation depends on whether trades have already been recorded. If no trades have been executed, the order can be cancelled.

When an order is cancelled, any reserved cash or units are released back to the account.

<Note>
  There is no cancel-order endpoint in the API. Orders are cancelled by our execution infrastructure when they can't be filled, or by our operations team when needed. You'll be notified via the `order.cancelled` webhook event.
</Note>

## Terminal states

An order is considered complete when it reaches one of these terminal states:

| Terminal state | Meaning                                             |
| -------------- | --------------------------------------------------- |
| `settled`      | The order was executed and all trades have settled. |
| `cancelled`    | The order was cancelled and won't be executed.      |

Your integration should handle both. Don't assume every order will eventually settle; always implement a path for cancellations.

## Webhook events

We fire an event whenever an order changes status. Subscribe to [webhooks](/docs/webhooks/overview) for real-time updates. In the sandbox environment, see [Testing](/docs/orders/testing) for which events each test order produces.

| Event             | Fired when                                          |
| ----------------- | --------------------------------------------------- |
| `order.placed`    | An order is accepted into the system.               |
| `order.pending`   | An order is waiting on a prerequisite.              |
| `order.executing` | An order is submitted for execution.                |
| `order.filled`    | An order is fully executed and trades are recorded. |
| `order.settled`   | All trades for an order have settled.               |
| `order.cancelled` | An order is cancelled.                              |

Related trade events:

| Event            | Fired when                            |
| ---------------- | ------------------------------------- |
| `trade.executed` | A trade is executed against an order. |
| `trade.settled`  | A trade settles.                      |

Event payloads don't carry the order data inline. Instead, they include a `resource` object with the order ID so you can fetch the latest state:

```json theme={"theme":"catppuccin-mocha"}
{
  "id": "evt_n8p3q1w5",
  "name": "order.filled",
  "resource": {
    "id": "ord_m4k7r9s2",
    "resource_type": "order"
  },
  "data": {},
  "created_at": "2026-03-12T14:30:05Z"
}
```

When you receive an order event, use the `resource.id` to call the [Retrieve order](/api-reference/retrieve-an-order) endpoint and get the order's current state. This ensures you're always working with the latest data, even if events arrive out of order.

<Warning>
  We may add new fields to event payloads at any time. Your integration should ignore unknown fields rather than failing on them.
</Warning>

<Note>
  Webhook delivery is at-least-once; your handler may receive the same event more than once. Use the event ID or `Webhook-Id` header to [deduplicate](/docs/webhooks/deliveries#handling-duplicates).
</Note>
