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

# Orderbook Trading

> Limit and market orders, time-in-force, direction, order flags, trigger and algo orders, replace, and cancellation.

Every order is placed with `private/order`, a signed [action](/authentication/action-signing) against the
`TRADE_MODULE`. The same payload shape describes limit and market orders, resting and
immediate orders, and (with a few extra fields) trigger and algo orders. This page covers the
enums and flags that shape order behaviour; see the **API Reference** tab for exact
field types and the full request/response schemas.

<Note>
  Prices, amounts, and fees (`limit_price`, `amount`, `max_fee`, `trigger_price`, `extra_fee`) are decimal strings. The
  signer signs the fixed-point encoding of these values as part of the EIP-712 action — see [Action
  signing](/authentication/action-signing).
</Note>

## Order type

`order_type` selects how the order interacts with the book. Default `limit`.

| Value    | Behaviour                                                                                 |
| -------- | ----------------------------------------------------------------------------------------- |
| `limit`  | Rests on the book at `limit_price` (subject to time-in-force).                            |
| `market` | Crosses the book immediately; any unfilled portion is cancelled rather than left resting. |

<Warning>
  `limit_price` is **required even for market orders** — it is a component of the order signature. For a market order it
  acts as a worst-acceptable price bound; the unfilled remainder is cancelled instead of resting.
</Warning>

## Time in force

`time_in_force` controls resting vs. immediate execution. Default `gtc`.

| Value       | Behaviour                                                                                      |
| ----------- | ---------------------------------------------------------------------------------------------- |
| `gtc`       | Good til cancelled — rests until filled, cancelled, or the signature expires.                  |
| `post_only` | Maker-only limit order; see [`reject_post_only`](#post-only) for cross handling.               |
| `fok`       | Fill or kill — rejected unless fully filled immediately.                                       |
| `ioc`       | Immediate or cancel — fills what it can at the limit (or market) price; the rest is cancelled. |

Orders always expire at `signature_expiry_sec` regardless of time-in-force. `market`, `ioc`,
and `fok` orders never leave a resting order in the book.

## Direction

`direction` is `buy` or `sell`.

## Order flags

<ParamField body="reject_post_only" type="boolean" default="true">
  Applies to `post_only` orders. When `true`, a post-only order that would cross the book is rejected. When `false`, its
  limit price is instead adjusted to one tick away from the best bid/offer so it rests as a maker order.
</ParamField>

<ParamField body="reduce_only" type="boolean" default="false">
  When `true`, the order can only reduce an existing position — never increase it. If the amount exceeds the current
  position size, the order fills up to that size and cancels the remainder. Supported only for market orders and
  non-resting limit orders (`ioc` or `fok`).
</ParamField>

<ParamField body="mmp" type="boolean" default="false">
  Tags the order for [Market Maker Protection](/trading/market-maker-protection). Tagged orders count toward the MMP counters
  and are cancelled when protection trips.
</ParamField>

<ParamField body="label" type="string">
  Optional client-defined tag (max 64 chars). Enables bulk cancel via `private/cancel_by_label`.
</ParamField>

`max_fee` is the max fee per unit of volume the signer accepts; the order is rejected if the
estimated fee exceeds it. Optional advanced fields include `referral_code`, `client`,
`reject_timestamp`, `extra_fee`, and `is_atomic_signing` (EIP-1271 atomic-signing orders).

### Place an order

<CodeGroup>
  ```typescript TypeScript (SDK) theme={null}
  import { DeriveClient } from '@derivexyz/sdk';

  const client = new DeriveClient({
    network: 'mainnet',
    wallet: process.env.PRIVATE_KEY!,
  });
  await client.connect();
  await client.login();

  const { order, trades } = await client.orders.place({
    subaccountId: 1234,
    instrumentName: 'ETH-PERP',
    direction: 'buy',
    orderType: 'limit',
    timeInForce: 'gtc',
    amount: '1.5',
    limitPrice: '3000',
    maxFee: '10',
    reduceOnly: false,
    mmp: false,
  });

  console.log(order.order_id, order.order_status);
  ```

  ```python Python (SDK) theme={null}
  # Coming soon.
  ```

  ```rust Rust (SDK) theme={null}
  // Coming soon.
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.derive.xyz/v3/order \
    -H "Content-Type: application/json" \
    -H "X-DeriveWallet: 0xYourWallet" \
    -H "X-DeriveTimestamp: 1695836058725" \
    -H "X-DeriveSignature: 0x…" \
    -d '{
      "subaccount_id": 1234,
      "instrument_name": "ETH-PERP",
      "direction": "buy",
      "order_type": "limit",
      "time_in_force": "gtc",
      "amount": "1.5",
      "limit_price": "3000",
      "max_fee": "10",
      "reduce_only": false,
      "mmp": false,
      "nonce": "1695836058725001000",
      "signature_expiry_sec": 1695836358,
      "signer": "0xYourWalletOrSessionKey",
      "signature": "0x…"
    }'
  ```

  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "private/order",
    "params": {
      "subaccount_id": 1234,
      "instrument_name": "ETH-PERP",
      "direction": "buy",
      "order_type": "limit",
      "time_in_force": "gtc",
      "amount": "1.5",
      "limit_price": "3000",
      "max_fee": "10",
      "reduce_only": false,
      "mmp": false,
      "nonce": "1695836058725001000",
      "signature_expiry_sec": 1695836358,
      "signer": "0xYourWalletOrSessionKey",
      "signature": "0x…"
    }
  }
  ```

  ```json Response theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "order": {
        "order_id": "8f7e…",
        "subaccount_id": 1234,
        "instrument_name": "ETH-PERP",
        "direction": "buy",
        "order_type": "limit",
        "time_in_force": "gtc",
        "order_status": "open",
        "amount": "1.5",
        "filled_amount": "0",
        "limit_price": "3000",
        "average_price": "0",
        "mmp": false,
        "nonce": "1695836058725001000"
      },
      "trades": []
    }
  }
  ```
</CodeGroup>

<Tip>
  Preview an order's price and fee without placing it using `public/order_quote` (unauthenticated) or
  `private/order_quote` (authenticated). Both take the **same fully-signed order payload** as `private/order` (including
  `nonce`, `signer`, `signature`, and `signature_expiry_sec`) — they simply return the quote instead of resting the
  order.
</Tip>

## Trigger (conditional) orders

Supply the trigger fields to submit a stop-loss or take-profit that stays dormant
(`order_status: untriggered`) until its trigger price is reached, then enters the book.

| Field                | Values                   | Notes                                |
| -------------------- | ------------------------ | ------------------------------------ |
| `trigger_type`       | `stoploss`, `takeprofit` | Required for a trigger order.        |
| `trigger_price_type` | `mark`, `index`          | Reference price the trigger watches. |
| `trigger_price`      | decimal string           | Price at which the order activates.  |

<Info>
  `trigger_price_type: index` is defined in the schema but not yet supported by the matching engine — use `mark`.
</Info>

Query and cancel trigger orders with `private/get_trigger_orders`,
`private/cancel_trigger_order` (by `order_id`), and `private/cancel_all_trigger_orders`.

## Algo orders

An algo order (e.g. slice-based execution) is submitted by supplying `algo_type` alongside
`algo_duration_sec` and `algo_num_slices`. Its lifecycle status is `algo_active`. Trigger and
algo fields are **mutually exclusive** — an order carrying both is rejected.

<Info>`twap` is currently the only supported `algo_type`; any other value is rejected.</Info>

Query and cancel algo orders with `private/get_algo_orders`, `private/cancel_algo_order`
(by `order_id`), and `private/cancel_all_algo_orders`.

## Replace (atomic cancel + replace)

`private/replace` atomically cancels an existing order and places a new one in a single call —
avoiding the race where a separate cancel-then-place leaves you briefly out of the book. The
payload is a `private/order` params object plus the cancel-target fields:

| Field                    | Notes                                                                                             |
| ------------------------ | ------------------------------------------------------------------------------------------------- |
| `order_id_to_cancel`     | The order to replace.                                                                             |
| `nonce_to_cancel`        | Cancel target by nonce (alternative to `order_id_to_cancel`).                                     |
| `expected_filled_amount` | Optional guard — the replace is rejected if the target's filled amount has moved past this value. |

## Cancelling orders

<CardGroup cols={2}>
  <Card title="Single order" icon="xmark">
    `private/cancel` — by `order_id` (plus `instrument_name`, `subaccount_id`).
  </Card>

  <Card title="By nonce" icon="hashtag">
    `private/cancel_by_nonce` — cancels the order(s) for a `nonce` on an `instrument_name`.
  </Card>

  <Card title="By instrument" icon="layer-group">
    `private/cancel_by_instrument` — all open orders on one `instrument_name`.
  </Card>

  <Card title="By label" icon="tag">
    `private/cancel_by_label` — all orders carrying a `label` (optionally scoped to one instrument).
  </Card>
</CardGroup>

`private/cancel_all` cancels every open order on a subaccount. Set `cancel_trigger_orders` and
`cancel_algo_orders` to also clear untriggered trigger orders and active algo orders.

<Note>For multi-leg block trades, use the [RFQ](/trading/rfq) workflow rather than individual orders.</Note>

Order-placing and cancel methods are rate-limited under the `matching` class (with
`cancel_all` under `endpoint` and `cancel_by_label` under `custom`); see
[Rate limits](/rate-limits).


## Related topics

- [Orderbook](/api-reference/channels/orderbook.md)
- [RFQ Trading](/trading/rfq.md)
- [Instrument Names](/trading/instrument-names.md)
