Skip to main content
Orders are how you buy and sell instruments on behalf of your customers. You submit an order through our API, and we handle validation, execution, and settlement asynchronously.

Before you start

To place an order, you’ll need:
  • An authenticated API session with a valid Bearer token
  • An account ID for the customer placing the order
  • The instrument ID for the security being traded; you can look these up via the instruments endpoints
  • Sufficient cash balance (for buy orders) or position units (for sell orders) in the account
You can check available cash and positions using the cash balances and positions endpoints before placing an order.In the sandbox environment, you can trigger predefined execution outcomes (cancel, partial fill, full fill) using specific cash_amount or quantity values. See Testing.

Placing an order

Send a POST request to /accounts/{account_id}/orders. The request body depends on whether you’re buying or selling.

Buy orders

Buy orders are cash-based: you specify how much money to invest, not how many units to buy. We calculate the quantity based on the current price, rounded down to the instrument’s trading_increment.

Sell orders

Sell orders are unit-based: you specify how many units to sell, not how much cash to receive.

Request body

Buy orders require cash_amount. Sell orders require quantity. Send exactly one of the two: we reject an order that sends both. The value must be greater than zero.

Sizing rules

Each instrument’s trading_configuration sets the rules an order must meet, separately for buy and sell: the modes it can be sized in and the minimums it must reach. A first buy (when the account holds no position in the instrument) must also meet min_initial_cash_amount and min_initial_quantity. Cash minimums apply to the amount invested after fees. A null minimum isn’t applied, and a sell minimum never blocks selling a whole position. An order that breaks one of these rules, or sends a quantity that isn’t a multiple of trading_increment, fails with trading_rule_violated (invalid_request on API versions before 2026-10-01). context.rule names the rule, with what it requires and what the order has.
Get an order quote first. A quote runs the same checks as placement, and when the order breaks a sizing rule it comes back with is_placeable: false and the rule in blockers. On a cash buy, context.required_cash_amount tells you the smallest cash_amount (fees included) that meets every buy rule.

The response

A successful request returns 201 Created with the order object:
Key fields to note:
  • status starts at placed. See the order lifecycle for how it progresses.
  • position is null until the order is executed; it gets populated when a trade is recorded.
  • traded_quantity and traded_notional are "0" initially and increase as trades execute.
  • fees reflects the total fee amount for this order.
  • net_cash_amount is the amount that actually gets traded (cash amount minus fees).
  • trades is an empty array until execution happens.
  • purpose is set by us. Orders you place through the API will always have user_request.
Order creation is synchronous; we validate the request and return the order immediately. Everything after that (execution, settlement) happens asynchronously. Use webhooks or poll the Retrieve order endpoint to track progress.

Retrieving orders

You can check an order’s current status at any time:
To list all orders for an account, use the List orders endpoint. To list only orders that haven’t reached a terminal state, use the List pending orders endpoint; this is useful for building dashboards or monitoring active trades.