tastytradeDeveloper Docs
Legacy ↗

Place an equity order

This how-to walks you through placing a single-leg equity order: build the order JSON, validate it with a dry run to confirm the buying-power and fee impact, then submit it with a unique external-identifier so retries stay safe.

This guide assumes you already have an access token. If not, see Get started. All examples use the sandbox base URL https://api.cert.tastyworks.com; swap in https://api.tastyworks.com for production.

Before you start

  • A 15-minute OAuth access token from POST /oauth/token.
  • Your account number (referenced below as {account_number}).
  • Every request must include a User-Agent: product/version header.
  • Order JSON uses dasherized keys (for example order-type, price-effect).

1. Build the order JSON

An equity order has order-level attributes plus a legs array. Equity orders are limited to a single leg. For a Limit order you must include both price and price-effect:

  • price-effect of Debit means money leaves your account (buying).
  • price-effect of Credit means money enters your account (selling).

Here is a realistic buy-to-open Limit order for 100 shares of AAPL at $175.25:

{
  "time-in-force": "Day",
  "order-type": "Limit",
  "price": "175.25",
  "price-effect": "Debit",
  "source": "my-api-code",
  "external-identifier": "aapl-buy-2026-06-09-0001",
  "legs": [
    {
      "instrument-type": "Equity",
      "symbol": "AAPL",
      "quantity": 100,
      "action": "Buy to Open"
    }
  ]
}

For an equity leg the symbol is just the ticker. The action combines side (buy/sell) with intent (open/close): use Buy to Open to open a long position and Sell to Close to close one. See /reference/orders for the full attribute reference and other order types (Market, Stop, Stop Limit, Notional Market).

2. Dry-run the order first

Always dry-run a money-moving order before submitting it. A dry run runs the same validations as a live order but routes nothing. Post the identical JSON to the dry-run endpoint:

curl -X POST "https://api.cert.tastyworks.com/accounts/{account_number}/orders/dry-run" \
  -H "Authorization: Bearer <access-token>" \
  -H "User-Agent: my-app/1.0.0" \
  -H "Content-Type: application/json" \
  -d @order.json

Inspect the response before going live:

  • buying-power-effect — how the order affects your account's buying power.
  • fee-calculation — estimated fees if the order fills.
  • closing-fee-calculation — estimated fees to later close the resulting position.
  • warnings — informational notices (for example, the market is closed). Some warnings indicate the order would be rejected if routed live.

A failed validation returns 422 with an error payload, for example cant_buy_for_credit if a buy order has "price-effect": "Credit". See /reference/errors for error codes.

3. Submit the order

Once the dry run looks correct, submit the same JSON to the live orders endpoint. The external-identifier field in the order JSON is your own unique identifier for this order. There is no idempotency-key header and the API does not deduplicate retried submissions — the identifier's job is to let you find the order again so you can check whether it already exists before resubmitting.

curl -X POST "https://api.cert.tastyworks.com/accounts/{account_number}/orders" \
  -H "Authorization: Bearer <access-token>" \
  -H "User-Agent: my-app/1.0.0" \
  -H "Content-Type: application/json" \
  -d @order.json

A successful submission returns the created order with a status of Routed, plus the same buying-power-effect and fee fields. The order object carries the order id and status you use for tracking and management, and echoes back your external-identifier. (Order responses also include a system-populated, read-only ext-client-order-id — that field is assigned by tastytrade and is not something you send.)

Retries and safety

If a submission times out or returns a 5xx, do not blindly resend it — the API does not deduplicate retried submissions, so a blind retry can place a duplicate order. Instead, first query GET /accounts/{account_number}/orders (or /accounts/{account_number}/orders/live) and look for an order with your external-identifier; resubmit only if it is absent. See Idempotency and retries for the full pattern. For 429 responses, back off per Rate limits and backoff.

Next steps