> ## 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.

# Testing

> Predefined order outcomes you can trigger in the sandbox environment

In the **sandbox environment**, order execution is deterministic. You exercise specific outcomes (full fill, unfilled cancel, or partial fill) by placing orders with particular field values. We ship a fixed set of scenarios; you **cannot** add or change them.

Testing execution is enabled on our side for the sandbox environment.

## How scenarios are selected

When we route your order for execution, we match it against a predefined list. The **first** scenario whose conditions all match wins. If nothing matches, you get the **default full fill**.

Matchers use the same fields you send when [placing an order](/docs/orders/overview):

* **Buy orders:** set `cash_amount` to the exact string shown below.
* **Sell orders:** set `quantity` to the exact string shown below (and do not set `cash_amount`).
* **Everything else:** default full fill.

<Warning>
  Trigger values must match **exactly**. Use `"5001"`, not `5001` or `"5001.00"`. A buy with `cash_amount` of `"5001.00"` will not hit the cancel scenario; it falls through to the default full fill. The same applies to sell `quantity` values (for example `"20"`, not `20` or `"20.00"`).
</Warning>

## Scenario reference

| Scenario                 | How to trigger                                       | Terminal status | Webhooks                                                               |
| ------------------------ | ---------------------------------------------------- | --------------- | ---------------------------------------------------------------------- |
| Unfilled cancel          | Buy, `cash_amount: "5001"`                           | `cancelled`     | `order.placed` → `order.executing` → `order.cancelled`                 |
| Partial fill (40%, buy)  | Buy, `cash_amount: "5002"`                           | `filled`        | `order.placed` → `order.executing` → `trade.executed` → `order.filled` |
| Full fill (buy)          | Buy, `cash_amount: "5003"`                           | `filled`        | `order.placed` → `order.executing` → `trade.executed` → `order.filled` |
| Full fill (sell)         | Sell, `quantity` of `"12"` or less, no `cash_amount` | `filled`        | `order.placed` → `order.executing` → `trade.executed` → `order.filled` |
| Partial fill (25%, sell) | Sell, `quantity: "20"`, no `cash_amount`             | `filled`        | `order.placed` → `order.executing` → `trade.executed` → `order.filled` |
| Default full fill        | Any other valid order                                | `filled`        | `order.placed` → `order.executing` → `trade.executed` → `order.filled` |

Some orders pass through `pending` before `executing`; many skip `pending` entirely. See the [order lifecycle](/docs/orders/lifecycle) for status definitions and the full webhook list.

## Partial fills

Partial scenarios are easy to misread. The order ends as **`filled`**, not `cancelled`: we execute part of the order, then cancel what is left. You get `trade.executed`, then `order.filled` (not `order.cancelled`). Use [Retrieve order](/api-reference/retrieve-an-order) or the trade resource to check `traded_quantity` and related fields.

| Trigger                    | Fill % | What to expect                                                                                                |
| -------------------------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| Buy, `cash_amount: "5002"` | 40%    | Roughly 40% of the order fills; exact trade `quantity` and `notional` depend on the instrument and your order |
| Sell, `quantity: "20"`     | 25%    | Trade `quantity` of `5`, then `order.filled`                                                                  |

The same triggers work for **currency pairs**. Statuses and webhooks match the table above; trade amounts follow your FX quote rather than the sell example.

## Examples

### Unfilled cancel

<CodeGroup>
  ```python Python theme={"theme":"catppuccin-mocha"}
  import requests

  response = requests.post(
      "https://api.engine.usesophic.com/accounts/{account_id}/orders",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "instrument": "ins_xyz789",
          "order_type": "market",
          "side": "buy",
          "cash_amount": "5001",
      },
  )
  order = response.json()
  ```

  ```javascript Node.js theme={"theme":"catppuccin-mocha"}
  const response = await fetch(
    "https://api.engine.usesophic.com/accounts/{account_id}/orders",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        instrument: "ins_xyz789",
        order_type: "market",
        side: "buy",
        cash_amount: "5001",
      }),
    }
  );
  const order = await response.json();
  ```
</CodeGroup>

Expect `order.cancelled` and a terminal status of `cancelled`. No `trade.executed` event.

### Partial fill

<CodeGroup>
  ```python Python theme={"theme":"catppuccin-mocha"}
  import requests

  response = requests.post(
      "https://api.engine.usesophic.com/accounts/{account_id}/orders",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "instrument": "ins_xyz789",
          "order_type": "market",
          "side": "buy",
          "cash_amount": "5002",
      },
  )
  order = response.json()
  ```

  ```javascript Node.js theme={"theme":"catppuccin-mocha"}
  const response = await fetch(
    "https://api.engine.usesophic.com/accounts/{account_id}/orders",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        instrument: "ins_xyz789",
        order_type: "market",
        side: "buy",
        cash_amount: "5002",
      }),
    }
  );
  const order = await response.json();
  ```
</CodeGroup>

Expect `trade.executed` followed by `order.filled`. The trade should reflect a partial fill (about 40% of the order); check the response for exact amounts.

### Sell partial fill

Use `quantity: "20"` and omit `cash_amount`:

<CodeGroup>
  ```python Python theme={"theme":"catppuccin-mocha"}
  import requests

  response = requests.post(
      "https://api.engine.usesophic.com/accounts/{account_id}/orders",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "instrument": "ins_xyz789",
          "order_type": "market",
          "side": "sell",
          "quantity": "20",
      },
  )
  order = response.json()
  ```

  ```javascript Node.js theme={"theme":"catppuccin-mocha"}
  const response = await fetch(
    "https://api.engine.usesophic.com/accounts/{account_id}/orders",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        instrument: "ins_xyz789",
        order_type: "market",
        side: "sell",
        quantity: "20",
      }),
    }
  );
  const order = await response.json();
  ```
</CodeGroup>

Expect `trade.executed` with `quantity` of `5`, then `order.filled`.

### Sell full fill

Use a quantity of `"12"` or less (for example `"10"`) and omit `cash_amount`:

<CodeGroup>
  ```python Python theme={"theme":"catppuccin-mocha"}
  import requests

  response = requests.post(
      "https://api.engine.usesophic.com/accounts/{account_id}/orders",
      headers={
          "Authorization": "Bearer YOUR_ACCESS_TOKEN",
          "Content-Type": "application/json",
      },
      json={
          "instrument": "ins_xyz789",
          "order_type": "market",
          "side": "sell",
          "quantity": "10",
      },
  )
  order = response.json()
  ```

  ```javascript Node.js theme={"theme":"catppuccin-mocha"}
  const response = await fetch(
    "https://api.engine.usesophic.com/accounts/{account_id}/orders",
    {
      method: "POST",
      headers: {
        Authorization: "Bearer YOUR_ACCESS_TOKEN",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        instrument: "ins_xyz789",
        order_type: "market",
        side: "sell",
        quantity: "10",
      }),
    }
  );
  const order = await response.json();
  ```
</CodeGroup>

Expect `trade.executed` with `quantity` of `10`, then `order.filled`.

## Tracking results

Subscribe to [webhooks](/docs/webhooks/overview) for real-time updates, or poll [Retrieve order](/api-reference/retrieve-an-order) after each placement. Webhook delivery is at-least-once; deduplicate using the event ID or `Webhook-Id` header.

<Note>
  Sandbox execution does not mirror production routing, venue behavior, or FIX lifecycles. Use it to test your integration against predictable order and trade outcomes, not to validate production execution logic.
</Note>
