> Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # tastytrade Developer Docs Agent-first API documentation for the tastytrade Open API. Browse the API Reference at `/reference` (96 operations). --- # Quickstart Get from nothing to your first authenticated call — and a safe sandbox order — in a few minutes. Use **sandbox** (`https://api.cert.tastyworks.com`) until you've verified your flow; production is `https://api.tastyworks.com`. ## 1. Get credentials You must have an OAuth client registered with tastytrade to use the API. You'll need your **client ID**, **client secret**, and a **refresh token** for that client — see [OAuth2](/docs/authentication/oauth2) for how tokens work. Sandbox and production credentials are **separate** — don't mix environments (check which base URL you're hitting). ## 2. Mint a 15-minute access token Exchange your refresh token for a short-lived access token via `POST /oauth/token`, sending `grant_type`, `refresh_token`, and `client_secret` in a JSON body (`client_id` is optional — if sent, it must match your client). See the [OAuth2 guide](/docs/authentication/oauth2) for the full token flow: ```bash curl -X POST 'https://api.cert.tastyworks.com/oauth/token' \ -H 'User-Agent: my-app/1.0' \ -H 'Content-Type: application/json' \ -d '{ "grant_type": "refresh_token", "refresh_token": "YOUR_REFRESH_TOKEN", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET" }' ``` The response contains your access token. It's valid for **15 minutes** — refresh when it expires (you can't extend one). > **Always send a `User-Agent`** in the form `/` (e.g. > `my-app/1.0`). Requests without one are rejected with a `401`. ## 3. Make your first call Send the token as a `Bearer` header on every request. List your accounts: ```bash curl 'https://api.cert.tastyworks.com/customers/me/accounts' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'User-Agent: my-app/1.0' ``` Then fetch balances for an account: ```bash curl 'https://api.cert.tastyworks.com/accounts/{account_number}/balances' \ -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \ -H 'User-Agent: my-app/1.0' ``` ## 4. Place an order — safely Order placement is **money-moving**, and the API does **not** deduplicate retried submissions. The golden path is **dry-run first**, then submit with a unique `external-identifier` you can check for before any retry: 1. **Dry-run** the order and confirm it returns no errors (check buying-power and fees). 2. **Submit** the real order including a unique `external-identifier`. 3. If the submit response is uncertain (timeout/`5xx`), **list your orders** (`GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`) and check for your identifier **before resubmitting** — see [Idempotency & retries](/docs/guides/idempotency-and-retries). See the [Orders reference](/reference/orders) for the order JSON, and [Rate limits & backoff](/docs/guides/rate-limits-and-backoff) for retry behavior. ## 5. Next steps - [API Reference](/reference) — all 98 operations, with schemas + code samples. - [MCP Server](/docs/sdks-and-tools/mcp-server) — drive trading from an AI agent, safely. - [Error reference](/reference/errors) — map any error code to its fix. - [`/llms.txt`](/llms.txt) — the machine-readable index for agents. ## Related - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Accounts & Customers](https://developer.tastytrade.com/docs/concepts/accounts-and-customers.md) --- # Agent Quickstart This is a single, self-contained walkthrough an AI agent can follow to complete a full trade in **sandbox**: discover the API, mint a token, fetch a quote, dry-run an order, submit it safely, and confirm the fill. Stay in sandbox (`https://api.cert.tastyworks.com`) until the whole flow is verified; production (`https://api.tastyworks.com`) is real money and requires explicit human approval. > **Consider the MCP server for autonomous flows.** The tastytrade > [MCP server](/docs/sdks-and-tools/mcp-server) is self-hosted and open source; its > five order-submitting tools are gated behind a dry-run-first confirmation token, > with sanity checks and rate limits on top. Note its default endpoint is > **production**. This page shows the raw HTTP golden path so you understand what > the MCP server does for you. > > Connecting an AI system to a tastytrade account carries its own risks — read > the [MCP server disclosures](/docs/sdks-and-tools/mcp-server#disclosures) first. Two rules apply to **every** request below: send `Authorization: Bearer ` and send a `User-Agent` header in the form `/` (e.g. `my-agent/1.0`). Requests without a `User-Agent` are rejected. Never log, echo, or commit tokens. ## 1. Discover the API Fetch [`/llms.txt`](/llms.txt) — the machine-readable index that points to every doc and reference page. Use it to locate endpoints instead of guessing. It is served by **this documentation site** (the same origin as this page), not by the trading API host. ```bash # Use this documentation site's origin — not api.cert.tastyworks.com curl 'https:///llms.txt' -H 'User-Agent: my-agent/1.0' ``` ## 2. Mint a 15-minute access token Exchange your refresh token for a short-lived access token. It is valid for **15 minutes** and cannot be extended — mint a fresh one when it expires. See [Get started](/docs/get-started) for obtaining credentials. ```bash curl -X POST 'https://api.cert.tastyworks.com/oauth/token' \ -H 'User-Agent: my-agent/1.0' \ -H 'Content-Type: application/json' \ -d '{ "grant_type": "refresh_token", "refresh_token": "YOUR_REFRESH_TOKEN", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET" }' ``` The response contains `access_token`. Then resolve your account number from `GET /customers/me/accounts`. ## 3. Fetch a quote Pull market data over REST for up to 100 symbols at once. Use tastytrade symbology: equities (`AAPL`), OCC equity options, futures (`/`-prefixed), future options (`./`-prefixed), and crypto pairs (`BTC/USD`). > **In the sandbox this request returns HTTP 502.** The sandbox does not serve > `/market-data` or `/market-metrics`. Read the quote from production with > separate credentials, or use the streaming feed described below. See > [Sandbox](/docs/sandbox). ```http GET /market-data/by-type?equity=AAPL Authorization: Bearer YOUR_ACCESS_TOKEN User-Agent: my-agent/1.0 ``` For live streaming, obtain an API quote token (`GET /api-quote-tokens`, 24h expiry) and connect to the DXLink WebSocket using the **COMPACT** format. See [Streaming](/docs/concepts/streaming). In the sandbox, for an account with a customer record, the token returned was `demo`-level with a `/delayed` URL. ## 4. Dry-run the order first Orders are **money-moving** — always dry-run first. Post the order body to the dry-run endpoint and confirm it returns **no errors**; inspect `buying-power-effect` and `fee-calculation` before going live. ```http POST /accounts/{account_number}/orders/dry-run Authorization: Bearer YOUR_ACCESS_TOKEN User-Agent: my-agent/1.0 Content-Type: application/json ``` ```json { "time-in-force": "Day", "order-type": "Limit", "price": "1.00", "price-effect": "Debit", "legs": [ { "instrument-type": "Equity", "symbol": "AAPL", "quantity": 1, "action": "Buy to Open" } ] } ``` Note the dasherized JSON keys (`order-type`, `price-effect`). A failed validation returns a `422` with an `error.code` you can branch on. ## 5. Submit with a unique `external-identifier` Once the dry-run is clean, submit to the live endpoint and include a unique **`external-identifier`** field in the order body. tastytrade has **no idempotency-key header** and does **not** deduplicate retried submissions, so this id is how you recognize your order on a retry. ```http POST /accounts/{account_number}/orders Authorization: Bearer YOUR_ACCESS_TOKEN User-Agent: my-agent/1.0 Content-Type: application/json ``` ```json { "time-in-force": "Day", "order-type": "Limit", "price": "1.00", "price-effect": "Debit", "external-identifier": "my-agent-2026-06-09-aapl-001", "legs": [ { "instrument-type": "Equity", "symbol": "AAPL", "quantity": 1, "action": "Buy to Open" } ] } ``` The `external-identifier` you send is echoed back on the order object. (Order responses and account-streamer messages also carry a system-populated, read-only `ext-client-order-id` — never try to set or send that field yourself.) If the submit response is uncertain (timeout or `5xx`), **do not blindly resubmit** — the server will not deduplicate. List your orders first (`GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/accounts/{account_number}/orders/live`) and check whether one carrying your `external-identifier` already exists. See [Idempotency & retries](/docs/guides/idempotency-and-retries). ## 6. Confirm the fill A successful submit returns an order with status `Routed`. Poll the order (or stream order updates) until it reaches a **terminal** status. The [lifecycle](/docs/concepts/order-lifecycle) flows roughly: `Received` → `Routed` → `In Flight` → `Live` → `Filled`. | Status | Terminal | Meaning | | --- | --- | --- | | Live | No | Working at the exchange | | Filled | Yes | Order fully filled — a position and transaction are created | | Cancelled | Yes | Order was cancelled | | Rejected | Yes | Rejected by tastytrade or the exchange | | Expired | Yes | Day order that did not fill before close | Once `Filled`, confirm by fetching the account's balances and positions. tastytrade may mark an order `Filled` before every leg's fills finish processing — if a leg looks short, re-fetch after a brief delay. ## Safety checklist - Sandbox until verified; get explicit human approval before production. - Dry-run first, then submit with a unique `external-identifier`. - On `429`, back off exponentially and retry — see [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). - Branch on the error **code**, not message text — see [Error reference](/reference/errors). ## Next steps - [API Reference](/reference) — all operations with schemas and samples. - [Orders reference](/reference/orders) — full order JSON, complex orders, fractional. - [MCP Server](/docs/sdks-and-tools/mcp-server) — the safe way to drive trading autonomously. **Disclosures:** connecting an AI system to your account is subject to the [tastytrade MCP Server Disclosures](/disclosures/tastytrade-mcp-server-disclosures.pdf). ## Related - [MCP Server](https://developer.tastytrade.com/docs/sdks-and-tools/mcp-server.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) --- # AI prompt for a personal app Many customers now use an AI coding assistant to write their first tastytrade API client. The API has a few requirements that are easy to miss: a `User-Agent` on every request, access tokens that last 15 minutes, dasherized JSON keys, and a dry-run before any order. This page gives you a prompt that already contains those details, so the assistant starts from what the API documents instead of from guesses. The prompt builds a small, read-only app for your own account. It does not build a trading app. It lists accounts, shows balances and positions, and downloads transaction history. Order JSON for a few standard strategies is included as reference only. ## Before you paste it 1. Create an OAuth application and a personal grant, and keep the client secret and refresh token to yourself. See [OAuth2 authentication](/docs/authentication/oauth2). Sandbox and production are separate applications with separate credentials. 2. Request only the scopes you need. Every call in this prompt is a read, and [reads need only the `read` scope](/docs/authentication/oauth2#what-can-go-wrong). 3. Set the credentials as environment variables in your own terminal. Do not paste them into the assistant's chat. 4. Start in the [sandbox](/docs/sandbox). Sandbox balances, positions and transactions are synthetic and reset every 24 hours, so they only show you that the code works. **Disclosures:** connecting an AI system to your account is subject to the [tastytrade MCP Server Disclosures](/disclosures/tastytrade-mcp-server-disclosures.pdf). ## The prompt Copy everything in the block below. Where it says "I", it means you. ```text You are helping me build a small PERSONAL command-line app for my own tastytrade account. It is READ-ONLY: it signs in with OAuth2, lists my accounts, shows balances and positions, and downloads transaction history. It is NOT a trading app. Use only the facts in this prompt. Do not rely on your memory of other tastytrade or tastyworks API examples; some describe a retired username/password login (POST /sessions) that no longer works. If you need an endpoint, field or behaviour that is not listed here, tell me and ask rather than guessing. The API reference is at https://developer.tastytrade.com/reference and an index for AI tools is at https://developer.tastytrade.com/llms.txt. If I have not said which language to use, ask me once, then continue. == SCOPE == Build exactly this and nothing more: 1. OAuth2 sign-in with a refresh token, and automatic access-token refresh. 2. List my accounts. 3. For an account I choose: show balances and show positions. 4. Download transaction history with pagination and an optional date range, printed as a table and optionally written to a CSV file. Do NOT build: order entry or management, streaming, market data, strategy or automation logic, scheduled jobs, a web UI, or a hosted service. Do not add features I did not ask for. == ENVIRONMENT AND SECRETS == - Base URL comes from the env var TASTYTRADE_BASE_URL. The default is the SANDBOX: https://api.cert.tastyworks.com Production is https://api.tastyworks.com. Never default to production. I will switch to it myself, only after the sandbox flow works. Print the base URL at every startup so I can see which environment I am using. - Sandbox and production use separate OAuth applications. Credentials from one do not work on the other, and the failure shows up as the error code invalid_credentials. - Read credentials ONLY from env vars: TASTYTRADE_CLIENT_SECRET and TASTYTRADE_REFRESH_TOKEN. TASTYTRADE_CLIENT_ID is optional. If you support a .env file, add .env to .gitignore and create only a .env.example with placeholder text. - Never hard-code a secret, token or account number, including in tests, examples and the README. Never log or print the client secret, refresh token or access token, including in error messages, exception traces and debug output of requests. Redact the Authorization header if you log requests. - Do not ask me to paste secrets into this chat. If an env var is missing, stop with a clear message that names the variable. - Use OAuth2 only. Never ask for or store my tastytrade username or password. == AUTHENTICATION: OAuth2 REFRESH-TOKEN FLOW == - To get an access token: POST {base}/oauth/token with Content-Type application/json and a JSON body containing grant_type set to "refresh_token", refresh_token, and client_secret. client_id is optional; if you send it, it must match my application. - The response contains access_token. Send it on every other request as the header Authorization: Bearer {access_token} - An access token is valid for 15 minutes and cannot be extended. - Refreshing does NOT return a new refresh token. Keep using the one from the env var, and do not overwrite or rotate it. - Keep the access token in memory only. Record when you received it, using a monotonic clock. Refresh before it expires: get a new token when the current one is more than 10 minutes old. Do not refresh before every request. - If a request returns 401 with a JSON body, refresh once and retry that one request once (not an order request). If it still returns 401, stop and report it. - Never retry a failed token request in a loop. Repeated failed logins can get my IP address blocked for about 8 hours. On any failure from /oauth/token, stop and show the HTTP status and error.code only. == EVERY REQUEST == - Send a User-Agent header in the form product/version, for example my-portfolio-viewer/1.0, on EVERY request including /oauth/token. Without it the API returns 401 even with a valid token, and the body is an HTML page, not JSON. - Send Accept: application/json and set a timeout on every request. - JSON keys are dasherized (account-number, net-liquidating-value). Use them exactly as returned. - List endpoints return the array in data.items. The balances endpoint returns one object in data. - Money amounts and quantities are JSON strings such as "100" or "27.74". Parse them with a decimal type, never a binary float. Amounts come with a separate field ending in -effect whose value is Credit, Debit or None. Keep that field next to the amount when you display it. == ENDPOINTS (these are the only ones you need) == 1. GET /customers/me/accounts Use the literal text "me". data.items is a list; each item has an "account" object (account-number, nickname, account-type-name, margin-or-cash, is-closed) and an "authority-level" (owner, trade-only or read-only). If I have more than one account, let me choose; do not assume the first. 2. GET /accounts/{account_number}/balances data is one object. Show cash-balance, net-liquidating-value, equity-buying-power, derivative-buying-power, maintenance-requirement, cash-available-to-withdraw and pending-cash. 3. GET /accounts/{account_number}/positions data.items is a list of open positions. Show symbol, instrument-type, underlying-symbol, quantity, quantity-direction (Long, Short or Zero), average-open-price, close-price and multiplier. Do not assume quantity is signed; use quantity-direction for the side. This endpoint returns no live profit/loss and no mark unless include-marks=true is set. Do not compute or show profit/loss. 4. GET /accounts/{account_number}/transactions Query parameters: page-offset (starts at 0), per-page (use 250), sort (Desc is newest first and is the default; Asc is oldest first), start-date and end-date (YYYY-MM-DD; end-date defaults to now). Optional filters: symbol, instrument-type, and types[] (repeat the key for several values). The response has data.items and a top-level pagination object with per-page, page-offset, item-offset, total-items, total-pages and current-item-count. Paging loop: start at page-offset=0 and keep per-page the same. Process data.items. Stop when page-offset + 1 >= pagination.total-pages. If there is no pagination object, stop when data.items is empty or has fewer than per-page entries. Otherwise add 1 to page-offset and fetch the next page, pausing briefly between pages. Show id, transaction-type, transaction-sub-type, description, symbol, action, quantity, price, value, value-effect, net-value, net-value-effect, executed-at and transaction-date. == ERRORS == Error bodies look like {"error": {"code": "...", "message": "..."}}. Branch on error.code, never on the message text. Show me the code and message. - 400: a bad parameter. Do not retry unchanged. - 401: see AUTHENTICATION. A 401 with an HTML body and no error.code means the User-Agent header is missing or malformed: fix the header, do not retry. error.code invalid_credentials usually means the credentials belong to the other environment: stop and tell me. - 403: the token's scope or the account's authority-level does not allow it. Do not retry. - 404: wrong account number, or wrong environment. Do not retry. - 422: the request is invalid in context. Read error.message and error.errors[], fix the cause, do not retry unchanged. - 429: too many requests. No rate-limit headers are documented, so do not depend on one. Back off exponentially with random jitter (about 1s, 2s, 4s, 8s), at most 5 attempts (not for order requests), then stop. Never retry in a tight loop. - 5xx and network errors: retry GET requests with the same backoff. Retry nothing else. == ORDERS: OUT OF SCOPE BY DEFAULT == This app is read-only. Do NOT write any code that places, replaces or cancels an order unless I explicitly ask for it in a later message. If I do ask, build the smallest thing that works and follow every rule here: a. Use the sandbox unless I explicitly say production. State the environment before any order action. b. First POST the order body to /accounts/{account_number}/orders/dry-run. It runs the preflight checks without routing the order and returns 201. Show me buying-power-effect, fee-calculation and warnings. Warnings are informational notices in data.warnings[] of a successful dry-run and do not block the order, but some indicate the order would be rejected if routed live. Treat ANY warning as a stop and show it to me. A dry-run that fails preflight is a 422; show me error.message and error.errors[]. c. Only after I have seen the dry-run output, ask me to type a confirmation that names this exact order (symbol, quantity, price). Then POST the identical body to /accounts/{account_number}/orders. Never submit from a loop, a schedule, a default or a --yes flag. d. Put a unique external-identifier (for example a UUID) in every order body. The API has no idempotency-key header and does NOT deduplicate retried submissions. Never retry an order request automatically. If a submit times out or returns 5xx, do not resubmit: GET /accounts/{account_number}/orders with a start-date on or before the day you submitted, in US Eastern time (for example, the previous day), or /accounts/{account_number}/orders/live, and look for that external-identifier first. e. Support only the three examples below. No other strategies, no complex or bracket orders, no futures, no cryptocurrency. Do not invent fields. The examples below are shapes, not trades. Replace the symbols, quantities and prices with values I give you. The option symbols below are from past expirations: take real ones from GET /option-chains/{symbol}/nested and copy them exactly, spaces included. For multi-leg orders, price is the net amount across all legs; price-effect is Debit if I pay and Credit if I receive. Keys are dasherized. Equity, limit buy of 100 shares: { "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" } ] } Vertical spread (a bear call vertical for a net credit): { "time-in-force": "Day", "order-type": "Limit", "price": "0.85", "price-effect": "Credit", "legs": [ { "instrument-type": "Equity Option", "symbol": "AAPL 221118C00155000", "quantity": 1, "action": "Sell to Open" }, { "instrument-type": "Equity Option", "symbol": "AAPL 221118C00157500", "quantity": 1, "action": "Buy to Open" } ] } Iron condor (four legs, net credit): { "source": "my-api-code", "order-type": "Limit", "time-in-force": "Day", "price": "1.51", "price-effect": "Credit", "legs": [ { "instrument-type": "Equity Option", "symbol": "TSLA 230714P00210000", "action": "Buy to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714P00215000", "action": "Sell to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714C00282500", "action": "Sell to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714C00290000", "action": "Buy to Open", "quantity": 1 } ] } For each of these, add your own unique external-identifier before the dry-run. == DELIVERABLES == - A few small files and a README with setup steps that use placeholder values only. - Tests, if any, use fake values and a mocked HTTP layer, never my real credentials. - Before you finish, check your own code: no hard-coded secrets, a User-Agent on every request including the token request, the sandbox as the default base URL, and no order code unless I asked for it. Then tell me plainly what you could not verify. ``` ## After the assistant answers Check the generated code against this list before you run it against anything but the sandbox. - Secrets are read from environment variables. Search the code for your client secret and refresh token, and for any `print` or log call near them. - Every request, including the token request, sends a `User-Agent`. - The default base URL is `https://api.cert.tastyworks.com`. - The access token is refreshed before 15 minutes and the refresh token is never overwritten. - The transaction loop stops on `pagination.total-pages`, and a `429` backs off instead of retrying at once. - There is no code that places an order, unless you asked for one. To use production, set `TASTYTRADE_BASE_URL` to `https://api.tastyworks.com` and use the production application's credentials. Do not change anything else at the same time. ## Next steps - [Agent Quickstart](/docs/agent-quickstart) — the raw HTTP path through a sandbox trade. - [Pagination and filtering](/docs/guides/pagination-and-filtering) — the transaction filters in detail. - [Error handling](/docs/guides/error-handling) — what each status means and which to retry. - [MCP server](/docs/sdks-and-tools/mcp-server) — an alternative to writing your own client. ## Related - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Agent Quickstart](https://developer.tastytrade.com/docs/agent-quickstart.md) - [Pagination & filtering](https://developer.tastytrade.com/docs/guides/pagination-and-filtering.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) --- # OAuth2 authentication Every request to the tastytrade API is authenticated with an OAuth2 access token in the `Authorization` header. All API users must use OAuth2 — the legacy `POST /sessions` flow was [decommissioned in 20260211](/docs/release-notes). Short-lived scoped tokens are the reason. A 15-minute access token limited to specific permissions gives an attacker a very small window and only the resources that token was authorized for. A 24-hour session token gives them a day with potentially full account access. ## Base URLs Sandbox and production are fully separate, with their own credentials and data. | Environment | Base URL | | --- | --- | | Production | `https://api.tastyworks.com` | | Sandbox | `https://api.cert.tastyworks.com` | A client and refresh token registered in one environment **will not work in the other**. See [Sandbox](/docs/sandbox) for what else differs. ## Every request needs a User-Agent All requests, including the OAuth calls below, must send a `User-Agent` header or they are rejected. The format is `product/version`. The product and version you pick do not matter as long as the format is right — most people make it specific to their client, like `tastytrade-api-client/1.0` or `my-custom-client/2.0`. ## Step 1 — Create an OAuth application On [my.tastytrade.com](https://my.tastytrade.com), go to **Manage → My Profile → API → OAuth Applications** and click **+ New OAuth client**. - **Client Name** is prefilled with your tastytrade username. - **Redirect URI**, one per environment requested. Multiple URIs are allowed, and each must be a full URI — `https://www.my-redirect-uri.com` is valid, `my-redirect.com` is not. - **Scopes**: `read`, `trade`, `openid`. On creation you are shown your **Client ID** and **Client Secret**. The client secret is shown **once**. Store it securely before clicking Finish Setup; it cannot be shown again. If you need a new one, use **Regenerate** at the top of the page — note that this **invalidates any active grants**. ![The Regenerate button on an OAuth application's settings page](/img/oauth/regenerate-client-secret.png) ## Step 2 — Generate a personal grant For your own application you do not need the full authorization flow. Go to **Manage → My Profile → API → OAuth Applications**, click **Manage** next to your application, then **Create Grant**. This shows your grant's **refresh token**. ![The Create Grant button on an OAuth application](/img/oauth/create-grant.png) Refresh tokens are long-lived and do not expire. If you lose one or it is compromised, delete the corresponding grant on the API page of [my.tastytrade.com](https://my.tastytrade.com) and create a new one — a new grant issues a new refresh token. ## Step 3 — Exchange the refresh token for an access token ```bash curl -X POST https://api.tastyworks.com/oauth/token \ -H "User-Agent: my-custom-client/1.0" \ -H "Content-Type: application/json" \ -d '{ "grant_type": "refresh_token", "refresh_token": "YOUR_REFRESH_TOKEN", "client_secret": "YOUR_CLIENT_SECRET" }' ``` `grant_type`, `refresh_token` and `client_secret` are required. `client_id` is optional — the server infers it from the refresh token, but if you send it, it must match. An optional space-separated `scope` requests a subset of your grant's scopes. The response contains a new `access_token`. Refreshing does **not** rotate your refresh token: none is returned, and the one you hold stays valid for the life of the grant. Access tokens are signed JWTs valid for **15 minutes**. An expired token returns HTTP 401. Refresh on a schedule, or lazily just before expiry, rather than on every request. ## Step 4 — Send the token on every request ```http GET /accounts/{account_number}/positions HTTP/1.1 Host: api.tastyworks.com Authorization: Bearer YOUR_ACCESS_TOKEN User-Agent: my-custom-client/1.0 Accept: application/json ``` Real access tokens are far longer than that placeholder. ## Third-party applications Everything above covers using your own application against your own account. A personal OAuth application is **restricted to your account only** — you can build and test, but other tastytrade users cannot connect to it. To let other users authorize your application you must complete tastytrade's trusted third party verification, which reviews how your application handles data and protects users. Contact [api.support@tastytrade.com](mailto:api.support@tastytrade.com) to start. **The rest of this section applies only to verified third party applications.** ### User authorization tastytrade supports the OAuth2 [authorization code grant](https://datatracker.ietf.org/doc/html/rfc6749#section-4.1). Once approved, direct users to `https://my.tastytrade.com/auth.html` (sandbox: `https://cert-my.staging-tasty.works/auth.html`) with: | Parameter | Required | | --- | --- | | `client_id` | yes | | `redirect_uri` | yes | | `response_type` | yes | | `scope` | no | | `state` | no | ![The tastytrade authorization screen a user sees](/img/oauth/authorize.png) On success the user is redirected to your `redirect_uri` with `code` (the authorization code) and `state` as query parameters. ### Exchange the code for tokens ```bash curl -X POST https://api.tastyworks.com/oauth/token \ -H "User-Agent: my-custom-client/1.0" \ -H "Content-Type: application/json" \ -d '{ "grant_type": "authorization_code", "code": "AUTHORIZATION_CODE", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "redirect_uri": "https://www.my-redirect-uri.com" }' ``` The response contains: | Field | Meaning | | --- | --- | | `access_token` | Send as a bearer token on each request | | `refresh_token` | Never expires | | `token_type` | `Bearer` | | `expires_in` | Seconds the access token remains valid | | `id_token` | Only returned when using the `openid` scope | Refresh works the same as [Step 3](#step-3-exchange-the-refresh-token-for-an-access-token). If a third-party refresh token is lost or compromised, contact tastytrade API support immediately. ### Two-factor authentication For sensitive scopes — currently **`read`** and **`trade`** — customers must have 2FA enabled to grant an application access. Customers enable it under [My Profile → Security](https://my.tastytrade.com/app.html#/manage/security) with either an authenticator app or SMS. ![Enabling two-factor authentication under My Profile Security](/img/oauth/2fa-enable.png) During authorization, after entering credentials and clicking Login, the customer is prompted for their 2FA code. ![The two-factor prompt during the authorization step](/img/oauth/2fa-prompt.png) ## What can go wrong - **401 Unauthorized** — no `Authorization` header, or the token is missing, invalid or expired. Refresh and retry. - **403 Forbidden** — the token is valid but not authorized for that resource: an account belonging to another customer, or a scope that does not cover the operation. Reads need `read`, mutations need `trade`. - **406 Not Acceptable** — the `Accept-Version` you sent no longer exists. See [API versions](/docs/concepts/api-versions). - **429 Too Many Requests** — back off and retry. See [Rate limits and backoff](/docs/guides/rate-limits-and-backoff). Error responses carry an `error` object with `code` and `message`. The full status code list is at [/reference/errors](/reference/errors). ## Notes for money-moving requests Run orders as a dry-run first, then submit with a unique `external-identifier` so you can recognise the order later. There is no idempotency-key header and the API does not deduplicate retried submissions. If a submission's outcome is uncertain after a timeout or 5xx, check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for your `external-identifier` before resubmitting. See [Idempotency and retries](/docs/guides/idempotency-and-retries). ## Related - [Quickstart](/docs/get-started) — your first authenticated call. - [Sandbox](/docs/sandbox) — separate credentials, and how fills are simulated. - [API versions](/docs/concepts/api-versions) — the `Accept-Version` header. - [MCP server](/docs/sdks-and-tools/mcp-server) — let it manage tokens for you. ## Related - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [MCP Server](https://developer.tastytrade.com/docs/sdks-and-tools/mcp-server.md) --- # Accounts & Customers Almost everything you do with the tastytrade API happens in the context of a **customer** and one of their **accounts**. Understanding that relationship is the key to navigating the rest of the reference: it tells you which path parameters an endpoint expects and which account a request will actually touch. ## The customer → accounts model A **customer** is the authenticated person (or entity) behind an access token. A customer has **one or more accounts** — for example, an individual margin account, a retirement account, and so on. Each account is identified by its `account-number` (e.g. `5WT00001`), and the **vast majority of trading, balances, positions, and order endpoints operate on a single account at a time**, addressed by that account number. So the typical flow after you authenticate is: 1. Read the customer (optional — mostly for profile/suitability data). 2. List the customer's accounts to discover their `account-number` values and your authority over each. 3. Make subsequent calls against a specific `account-number`. ## The `me` shortcut For simplicity and security, tastytrade does **not** expose a customer's internal identifier through the API. Wherever a customer endpoint takes a `customer_id` path parameter, the **only accepted value is `me`**, which resolves to the customer linked to the access token you authenticated with. ```http GET /customers/me GET /customers/me/accounts GET /customers/me/accounts/{account_number} ``` `GET /customers/me` returns the customer's profile, including address, contact, suitability, and identity data. `GET /customers/me/accounts` lists every account the customer can access. You can fetch a single account directly with `GET /customers/me/accounts/{account_number}` (note that `{account_number}` is a path parameter — substitute the real account number). ```bash curl -s https://api.cert.tastyworks.com/customers/me/accounts \ -H "Authorization: Bearer " \ -H "User-Agent: my-app/1.0.0" ``` Use the sandbox base URL `https://api.cert.tastyworks.com` while developing and `https://api.tastyworks.com` for production. Every request must send a `User-Agent` header in the form `/`, and OAuth access tokens are short-lived (15 minutes) — refresh them via `POST /oauth/token`. See [Get started](/docs/get-started) for the full handshake. ## Authority levels Listing accounts returns an `authority-level` for each one, describing what the authenticated customer is allowed to do with that account. The account itself lives under an `account` object; the authority is reported alongside it. | Authority level | What it allows | | --- | --- | | `owner` | Full privileges over the account | | `trade-only` | Can submit and manage trades, but cannot move money (e.g. deposit/withdraw cash) | | `read-only` | Can call all `GET` endpoints for the account, but cannot trade | Always check the authority level before attempting a write. A `read-only` or `trade-only` authority will cause money-moving or trading requests to be rejected — typically with a `403` (see [error codes](/reference/errors)). ```json { "account": { "account-number": "5WT00001", "nickname": "Individual", "account-type-name": "Individual", "margin-or-cash": "Margin", "is-closed": false, "is-futures-approved": true }, "authority-level": "owner" } ``` Responses use **dasherized JSON keys** (`account-number`, `authority-level`), and account-scoped collections are wrapped in a `data.items` array with a `context` echoing the request path. ## Acting on an account Once you have an `account-number`, you can read balances and positions and place orders against it. Because orders move money, follow the standard discipline: **dry-run first**, then submit the live order with a unique client-supplied `external-identifier`. The API does **not** deduplicate retried submissions and there is no idempotency-key header — if a submission times out or fails ambiguously, check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), for your identifier before resubmitting. See [Idempotency & retries](/docs/guides/idempotency-and-retries) and [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). ## Reference For the full request/response schemas of these endpoints, see [Accounts & Customers in the API reference](/reference/accounts-and-customers) and the broader [reference](/reference). ## Related - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Positions & Balances](https://developer.tastytrade.com/docs/concepts/positions-and-balances.md) - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) --- # Instruments & Symbology An **instrument** is any single tradeable security at tastytrade: an equity, equity option, future, future option, or cryptocurrency. Every instrument has a unique **symbol** that is its primary identifier. You need that symbol to look up an instrument, to build order legs, and to read the positions an order creates. Getting symbology right is therefore the foundation of every trading workflow. This page explains the symbol format for each instrument type and where those symbols show up. For the full request/response shapes, see [`/reference/instruments`](/reference/instruments). ## How symbols flow through the API The same symbol string is reused across the platform: - **Instrument lookup** — fetch an instrument's full definition under `/instruments/...`. - **Order legs** — each leg references a symbol plus an instrument type, quantity, and action. - **Positions** — when an order fills, the resulting position carries the same symbol. Because symbols are passed verbatim, encoding matters. Symbols that contain a `/` (futures, future options, crypto) or whitespace (OCC options) **must be URL-encoded** when placed in a path or query string. For example `/ESU3` becomes `%2FESU3`, and `BTC/USD` becomes `BTC%2FUSD`. JSON bodies use the raw, unencoded symbol. A few platform conventions apply to every instrument request. Send a `User-Agent` header in `product/version` form (for example `my-client/1.0`) or the request is rejected, set `Content-Type` and `Accept` to `application/json`, and authenticate with a short-lived OAuth access token (`Authorization: Bearer ...`). Access tokens are minted by `POST /oauth/token` and expire after 15 minutes. JSON keys are dasherized, e.g. `instrument-type` and `streamer-symbol`. See [Get started](/docs/get-started) for the full setup. ## Equities Equity symbols are alphanumeric (A-Z, 0-9), occasionally containing a `/`: ``` AAPL BRK/A ``` Each equity also exposes a `streamer-symbol` used by the market-data streamer, plus flags like `is-index`, `is-etf`, and `is-fractional-quantity-eligible`. ## Equity options (OCC) tastytrade uses the standard **OCC** format. A symbol is a fixed-width concatenation of four parts: 1. **Root** — up to 6 alphanumeric characters, right-padded with spaces. 2. **Expiration** — 6 digits, `yymmdd`. 3. **Type** — `C` (call) or `P` (put). 4. **Strike** — 8 digits, front-padded with zeros, strike multiplied by 1000 (no decimal point). ``` AAPL 220617P00150000 (AAPL Jun 17 2022 150 Put) SPY 221118C00400000 (SPY Nov 18 2022 400 Call) SPXW 220520C04025000 (SPXW May 20 2022 4025 Call) ``` The strike rule: a 64.0 strike is `00064000`, a 1050.55 strike is `01050550`, a 0.50 strike is `00000500`. Note the padding spaces between root and expiration are significant. ## Futures (prefixed `/`) Futures symbols start with a `/` followed by a contract code: product code (A-Z), a one-letter month code, and a 1-2 digit year. ``` /ESZ2 (E-mini S&P 500, December 2022) /CLZ2 (Crude Oil, December 2022) /VXX22 (CBOE Volatility Index, November 2022) ``` Product codes come from the future-products listing under `/instruments`. Remember to encode the leading `/` as `%2F` in URLs. ## Future options (prefixed `./`) Each future option **expiration series** has its own product code, so a future option symbol carries both the future contract code and the option product code. The format is `./` + future contract code + option contract code + expiration + type (`C`/`P`) + strike: ``` ./CLZ2 LO1X2 221104C91 (Nov 4 2022 91 Call settling into Dec CL) ./ESZ2 E1AZ2 221205P3720 (Dec 5 2022 3720 Put settling into Dec ES) ``` In `./ESZ2 E1AZ2 221205P3720`, `E1A` is a weekly-Monday option product, `ESZ2` is the underlying December ES contract. Encode the `./` prefix (and embedded spaces) for URLs, e.g. `.%2FESZ2%20E1AZ2%20221205P3720`. ## Cryptocurrencies Crypto symbols are a pair joined by `/`: ``` BTC/USD (Bitcoin) BCH/USD (Bitcoin Cash) ``` The authoritative list is returned by `GET /instruments/cryptocurrencies`. Crypto is commonly traded in fractional quantities; the allowed precision is given per symbol (for example BTC/USD permits 8 decimal places). Encode the `/` as `%2F` in URLs. ## Using symbols in orders When you place an order, each leg references one of these symbols. Always submit a **dry-run** first to validate buying power and pricing before sending the live order. Order submission is **not idempotent** and there is no idempotency-key header — the API does not deduplicate retried submissions. Include a unique `external-identifier` in the order body so you can correlate it later; if a submission's outcome is uncertain (timeout or 5xx), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), for that identifier **before** resubmitting. See [Idempotency & retries](/docs/guides/idempotency-and-retries) and [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). ## Errors Lookups return standard codes: `400` (malformed request), `401` (missing/expired token), `404` (unknown symbol or endpoint), `422` (invalid filter combination — e.g. filtering future options by `expiration-date` alone, without the other required filters), `429` (rate limited), and `5xx` (server error). See [Errors](/reference/errors) for the full platform-wide set. ## Related - [Instruments reference](/reference/instruments) — every endpoint, parameter, and response field. - [Reference](/reference) — full API surface. - [MCP server](/docs/sdks-and-tools/mcp-server) — query instruments via tools. ## Related - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Multi-leg spreads](https://developer.tastytrade.com/docs/guides/multi-leg-spreads.md) - [Market Data](https://developer.tastytrade.com/docs/concepts/market-data.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) --- # Dates & Times REST request and response fields that hold a date or a moment in time are declared in the OpenAPI specs as `date` or `date-time`, and the reference pages show that format next to the field. Some timestamp fields, such as `updated-at` on orders and `expires-at` on quote alerts, declare no `format` at all and show as a plain `string`. For those, rely on the example and the description. A few fields are not strings at all: see [Epoch values](#epoch-values). ## Two formats | Spec `format` | Shape | Example | Used for | | ------------- | ----------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------- | | `date` | `YYYY-MM-DD` | `2026-06-08` | Calendar days: `start-date`, `end-date`, `snapshot-date`, `session-date` | | `date-time` | `YYYY-MM-DDThh:mm:ss.sssZ` or `...+00:00` | `2024-01-15T14:30:00.000Z` | Moments: `created-at`, `updated-at`, `received-at`, `expires-at`, `open-at`, `close-at` | In the specs, `updated-at` and `expires-at` are declared `date-time` on some schemas and carry no `format` on others, so the table lists the fields that use each form, not a guarantee for every schema. A plain date names a day and carries no time or offset. A date-time names an exact moment. ## Parse the offset, don't match the text The published examples show a UTC moment written two ways: with a trailing `Z` (`2024-01-15T14:30:00.000Z`) and with an explicit offset (`2024-07-31T16:50:23.417+00:00`). Both mean the same thing. Parse timestamps with an ISO 8601 parser that understands offsets, and compare the parsed values. Comparing the raw strings, or hashing them, will treat two equal moments as different. Fractional seconds can also vary in length, so don't assume a fixed number of digits. ## Date or date-time in a query Several endpoints that filter by time accept both forms as separate parameters, for example `start-date` / `end-date` and `start-at` / `end-at` on transactions and orders. - Use the `-date` pair to bound a query to whole days. - Use the `-at` pair when you need a specific moment inside a day. Check the reference page for the endpoint you're calling. See [Pagination & Filtering](/docs/guides/pagination-and-filtering) for the filters the transactions endpoint supports. ## Market hours Session times such as `open-at` and `close-at` come back as date-times. The regular equity open is 9:30 a.m. in New York, which is `13:30` UTC during daylight saving time and `14:30` UTC otherwise, so a fixed offset will be wrong for part of the year. Read session times from the Market Sessions endpoints instead of hard-coding them. ## Epoch values Not every time value is an ISO 8601 string. In the Market Data reference, `haltStartTime`, `haltEndTime` and `lastTradeTime` are epoch timestamps, and the two halt fields are `-1` when the security is not halted. In the streaming API, the `timestamp` on a notification is epoch milliseconds, and the `fromTime` on a Candle subscription is epoch seconds. The DXLink `Profile` event's `haltStartTime` and `haltEndTime` are epoch milliseconds too, according to dxFeed's event documentation. Check each field's description for its unit before parsing it as a date. ## Related - [Pagination & filtering](https://developer.tastytrade.com/docs/guides/pagination-and-filtering.md) - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Positions & Balances](https://developer.tastytrade.com/docs/concepts/positions-and-balances.md) --- # Orders & Order Types An order in the tastytrade API is a JSON document with two parts: **order attributes** that apply to the trade as a whole, and a **legs** array where each leg names a single instrument, a side, and a quantity. All JSON keys are **dasherized** (for example `order-type`, `price-effect`, `time-in-force`, `instrument-type`), and prices/values are sent as strings or decimals. Orders are submitted to `POST /accounts/{account_number}/orders`. Because orders move real money, **always dry-run first** against `POST /accounts/{account_number}/orders/dry-run` (the same JSON body), inspect the returned `buying-power-effect`/`fee-calculation` and any `warnings`, then submit. There is **no** idempotency-key header and the API does **not** deduplicate retried submissions, so set your own unique `external-identifier` on each order (it is echoed back on the order response); if a submission's outcome is uncertain (timeout or `5xx`), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for that identifier **before** resubmitting. See [Idempotency & retries](/docs/guides/idempotency-and-retries) and the full schema at [/reference/orders](/reference/orders). ## Order attributes | Attribute | Required | Meaning | | --- | --- | --- | | `order-type` | Yes | The kind of order (see below) | | `time-in-force` | Yes | How long the order lives if unfilled | | `price` | Yes for `Limit` / `Stop Limit` | The limit price | | `price-effect` | With `price` | `Debit` (you pay) or `Credit` (you receive) | | `stop-trigger` | Yes for `Stop` / `Stop Limit` | The trigger price | | `gtc-date` | Yes for `GTD` | Expiry date (`yyyy-mm-dd`) | | `value` / `value-effect` | Yes for `Notional Market` | Dollar amount to buy/sell | | `legs` | Yes | Array of leg objects | | `source` | No | Free-form origin tag | `price-effect` must agree with the leg action: buying is a `Debit`, selling is a `Credit`. Buying for a credit (or selling for a debit) is rejected. ## Legs Each leg names one instrument. All orders need at least one leg. Equity, future, and cryptocurrency orders are limited to **1 leg**; equity-option and future-option orders allow up to **4 legs**. Two legs may not share the same `symbol`. | Leg attribute | Required | Meaning | | --- | --- | --- | | `action` | Yes | `Buy to Open`, `Sell to Open`, `Buy to Close`, `Sell to Close` (or `Buy`/`Sell` for single-leg outright futures) | | `instrument-type` | Yes | `Equity`, `Equity Option`, `Future`, `Future Option`, or `Cryptocurrency` | | `quantity` | Yes (omit for `Notional Market`) | Whole number, or decimal for crypto | | `symbol` | Yes | The instrument symbol | The `action` and `instrument-type` values above are the commonly used ones — the full enums (which also include `Allocate`, `Equity Offering`, `Fixed Income Security`, and `Liquidity Pool`) are in [/reference/orders](/reference/orders). Symbols follow tastytrade symbology: plain tickers for equities (`AAPL`), OCC-style strings for equity options (`AAPL 230818C00197500`), leading-slash futures (`/CLZ2`), future options, and crypto pairs (`BTC/USD`). Look symbols up via the instruments endpoints — see [/reference](/reference). ## Order types | Type | Rule | | --- | --- | | `Limit` | Must include `price` and `price-effect` | | `Market` | No `price`/`price-effect`; single leg; `time-in-force` not `GTC` (for cryptocurrency orders the `time-in-force` rules are the [crypto rules](#cryptocurrency-orders) instead; the other `Market` rules still apply) | | `Stop` | Market order with a `stop-trigger`; becomes a market order when the quote hits the trigger | | `Stop Limit` | Limit order (`price` + `price-effect`) plus a `stop-trigger` | A `Notional Market` type also exists for buying a dollar `value` of crypto or eligible equities (omit `quantity`). These are the commonly used order types — the full `order-type` enum (which also includes `Marketable Limit` and `Liquidity Allocation`) is in [/reference/orders](/reference/orders). ```json { "time-in-force": "Day", "order-type": "Limit", "price": "1.09", "price-effect": "Debit", "legs": [ { "instrument-type": "Equity Option", "symbol": "AAPL 230818C00197500", "quantity": 1, "action": "Buy to Open" }, { "instrument-type": "Equity Option", "symbol": "AAPL 230818C00200000", "quantity": 1, "action": "Sell to Open" } ] } ``` ## Time-in-force | TIF | Meaning | | --- | --- | | `Day` | Works until filled or the market closes | | `GTC` | Good 'til canceled — works until filled or canceled | | `GTD` | Good 'til date — also requires `gtc-date` (`yyyy-mm-dd`) | Some venues also support immediate-or-cancel and extended-hours behaviors; refer to [/reference/orders](/reference/orders) for the values your instrument accepts. ## Cryptocurrency orders > **Cryptocurrency trading is currently disabled through the API.** The [release notes](/docs/release-notes) record that it was disabled as of release `20260629`, until further notice. The rest of this section describes the order shape for when it is enabled; do not build against it before the release notes say it is back. The `is-cryptocurrency-enabled` and `is-cryptocurrency-closing-only` fields returned by `GET /accounts/{account_number}/trading-status` are per-account flags for whether an account may trade cryptocurrency. They do not say whether the API currently accepts crypto orders. Cryptocurrency orders use the same `POST /accounts/{account_number}/orders` endpoint and body as any other order, with `instrument-type` set to `Cryptocurrency` and a pair symbol such as `BTC/USD`. **Finding supported products.** `GET /instruments/cryptocurrencies` returns the active crypto instruments (filter with `symbol[]=BTC%2FUSD`; URL-encode the `/`). Use each instrument's `symbol` field as the leg `symbol`. An instrument with `is-closing-only` set to `true` accepts only closing orders. **Quantity and price precision.** - Quantity may be a decimal for crypto. `GET /instruments/quantity-decimal-precisions` returns, per instrument type or symbol, a `value` giving the number of decimal places a quantity may use (`0` means whole numbers only). In the reference example BTC/USD has a `value` of `8`, so `0.12345678` is valid and `0.123456789` is not. - Price: an opening order's `price` must follow the instrument's `tick-size`. A closing order's `price` may use any number of decimal places up to the highest `max-price-precision` among the instrument's `destination-venue-symbols` entries that have `routable` set to `true`. See the [instruments reference](/reference/instruments) and the rules below. **Order shape.** A crypto order has a single leg. Send a decimal `quantity` as described above, or use a `Notional Market` order that buys a dollar `value` and omits `quantity`. A `Notional Market` example: ```json { "time-in-force": "IOC", "order-type": "Notional Market", "value": "10.0", "value-effect": "Debit", "legs": [ { "instrument-type": "Cryptocurrency", "symbol": "BTC/USD", "action": "Buy to Open" } ] } ``` **Order rules and limits.** The order service's own checks on a cryptocurrency order are listed below. They apply when crypto trading is available to your account and client, and say nothing about whether that is the case today; the notice at the top of this section does. The order types and `time-in-force` values listed are the ones the order service's code accepts. They are not a guarantee that a given combination is accepted on submission; see the venue rules note after the table. | Rule | What the order service enforces | Rejection code | | --- | --- | --- | | Legs | Exactly one leg | `cryptocurrency_single_leg_only` | | Action | `Buy to Open` or `Sell to Close`. `Buy to Close` is accepted only for orders the service treats as forced. | `cryptocurrency_invalid_action` | | Order type | `Limit`, `Market`, or `Notional Market` | `cryptocurrency_invalid_type` | | Time in force | `IOC` or `GTC`; any other value is rejected. A `Notional Market` order must be `IOC`. | `tif.cryptocurrency_invalid`, `cryptocurrency_notional_market_orders_ioc_only` | | `gtc-date` | Must not be set | `cryptocurrency_no_gtc_date` | | Maximum quantity | 2,147,483,647 per leg | `order_limit_check_failed` | | Minimum notional value | $1 for an order with an opening leg; $0.01 for a closing order. The rejection message formats the minimum with no decimals, so for a closing order it reads "$0". | `below_notional_value_minimum` | | Maximum notional value | $75,000 | `above_notional_value_maximum` | | Opening price | Must follow the instrument's `tick-size` (checked when the order has a `price`) | `invalid_price_increment` | | Closing price | At most the highest routable `max-price-precision` decimal places (checked when the order has a `price`). If the instrument has no routable `destination-venue-symbols`, the limit is the number of decimal places in its `tick-size`. | `cryptocurrency_invalid_closing_price` | | Price band, buy | A `Limit` buy price may be at most 1.20 times the current ask | `cryptocurrency_unreasonable_price_max` | | Price band, sell | A `Limit` sell price may be at most 1.55 times the current ask | `cryptocurrency_unreasonable_price_max` | | Price band, minimum | A `Limit` price may not be below 0.25 times the current bid | `cryptocurrency_unreasonable_price_min` | The notional-value limits are checked on the order's notional value as the order service calculates it, for every crypto order type and not only `Notional Market`. The quantity limit is a fixed ceiling, not a statement of what the instrument accepts; the quantity precision rules above still apply. The quantity limit, the notional limits and the price-band multipliers are fixed values in the order service's code, not account settings. The message for `order_limit_check_failed` is in the [preflight error list](/reference/errors#order_limit_check_failed); it suggests contacting the trade desk to increase your limits, but the crypto quantity limit is this fixed value, so that advice does not apply to it. **Venue rules and dry-run.** The table lists the order service's own checks. On submission the service also matches the order against routing-venue rules that are stored in a database. Those rules can further restrict order type and time in force (each type and each time in force is a separate on/off setting, for example `Market`, `Notional Market`, `IOC` and `GTC`). The same venue selection also checks that the symbol is routable and checks quantity and price precision. If no venue accepts the order, it is rejected with `cryptocurrency_venue_not_found`. If a venue matches but no compatible order router is left for it, the rejection is `no_router_found` ("No compatible order router found."). A dry-run does not run this step, so a dry-run that passes does not guarantee that the order will be accepted on submission. The venue rules are not published, so this page does not say which type and `time-in-force` combinations are enabled; in particular it does not say whether a `Market` order with `GTC` is accepted, even though no crypto check in the table rejects it. **Blocked for API clients.** The order service can block an instrument type for API clients. When it does, an order from an OAuth2 client for that type is rejected with a `422`, and the entry in `error.errors[]` is: ```json { "code": "api_forbidden_type", "message": "Order contains instrument types that are not currently allowed for API trading: " } ``` Orders sent without an OAuth2 client are not checked, and clients the service has allowlisted are exempt. Which types are blocked, and which clients are allowlisted, is service configuration that is not published, so this page does not say whether `api_forbidden_type` is how crypto is disabled today. The same check can reject specific symbols with the code `api_forbidden_symbol`. Preflight stops at the first stage that reports an error. The crypto gatekeeper stage runs before the blocked-type check, so an order it rejects with `cryptocurrency_trading_not_supported` ("Cryptocurrency trading is not supported.") or `cryptocurrency_not_allowed` ("Your account is not approved for cryptocurrency trading. Please enable it to trade this product.") never reaches it. The blocked-type check in turn runs before the order-shape and limit checks in the table, so a blocked order is rejected with `api_forbidden_type` even if it also breaks one of those rules. A failed pre-submission check comes back as a `422` with a `preflight_check_failure` code (see [Errors](/reference/errors)); each failure is an entry in `error.errors[]` with its own `code`. ## Complex orders Complex (bracket) orders are submitted to `POST /accounts/{account_number}/complex-orders` and have a `type` plus an `orders` array (and, for triggered types, a `trigger-order`; PAIRS adds ratio-price fields — see below). Supported types are **OTOCO**, **OCO**, **OTO**, and **PAIRS**. `BLAST` is deprecated and is not supported in any environment. - **OTO** — the `trigger-order` goes live immediately; when it fills, its `orders` (up to 3) are routed. They do not cancel one another. - **OCO** — no `trigger-order`; the `orders` go live immediately, and when one fills the other is canceled. - **OTOCO** — a `trigger-order` plus one to three OCO pairs (2, 4 or 6 `orders`) that sit in `Contingent` status until the trigger fills, then route as OCOs. - **PAIRS** — `orders` worked together as a pairs strategy, triggered by a ratio price: set `ratio-price-comparator` (`gte` or `lte`) and `ratio-price-threshold` (a decimal serialized as a JSON string, e.g. `"150.25"`); optionally set `ratio-price-is-threshold-based-on-notional` to compare on notional value instead of price. A working PAIRS order's threshold and comparator can later be edited via `PATCH /accounts/{account_number}/complex-orders/{id}` (only PAIRS orders can be edited there). ```json { "type": "OTOCO", "trigger-order": { "order-type": "Limit", "price": 157.97, "price-effect": "Debit", "time-in-force": "Day", "legs": [{ "instrument-type": "Equity", "symbol": "AAPL", "action": "Buy to Open", "quantity": 100 }] }, "orders": [ { "order-type": "Limit", "price": 198.68, "price-effect": "Credit", "time-in-force": "GTC", "legs": [{ "symbol": "AAPL", "instrument-type": "Equity", "action": "Sell to Close", "quantity": 100 }] }, { "order-type": "Stop", "time-in-force": "GTC", "stop-trigger": 143.06, "legs": [{ "symbol": "AAPL", "instrument-type": "Equity", "action": "Sell to Close", "quantity": 100 }] } ] } ``` The response returns a `complex-order.id` (used to fetch or cancel the whole bracket) plus individual `id`s for the trigger and nested orders. Cancel a complex order through its own endpoint using the complex-order id, not a nested order id. ### Price restrictions on triggered orders An **OTOCO** order is checked to make sure its `orders` are priced sensibly relative to the `trigger-order`: in each OCO pair, the profit-taking order has to sit on the profitable side of the trigger order's price, and the stop-loss order on the other side. This check runs for OTOCO only; it is not applied to OTO, OCO, or PAIRS orders. It applies to every order in `orders`, except that an order in `orders` that has already reached a terminal status is skipped. Each order in `orders` is compared against a **reference price**, strictly (equal prices are rejected). Credit or debit is taken from the order's `price-effect`; if it has none (as with the `Stop` in the example above, which has no `price`), from its `value-effect`, and for a single-leg order after that from the leg action (a buy is a debit, a sell is a credit): | Order in `orders` (credit or debit) | Price that is compared | Must be | | --- | --- | --- | | Credit, `Limit` | `price` | greater than the reference price | | Credit, `Stop` | `stop-trigger` | less than the reference price | | Credit, `Stop Limit` | `price` (the limit price, not `stop-trigger`) | less than the reference price | | Debit, `Limit` | `price` | less than the reference price | | Debit, `Stop` | `stop-trigger` | greater than the reference price | | Debit, `Stop Limit` | `price` (the limit price, not `stop-trigger`) | greater than the reference price | In other words, for a long trigger order the profit order must be priced above the trigger price and the stop-loss below it; for a short trigger order the profit order must be priced below and the stop-loss above. A `Market` order cannot be used in `orders`: it has no price to compare, so it fails this check. The reference price is the trigger order's `price` for a `Limit` or `Stop Limit` trigger order, or its `stop-trigger` for a `Stop` trigger order. If the trigger order has no price (a `Market` order), or if it has already filled, the current mid price of the trigger order's legs is used instead (the last trade price for any leg that has no mid). If a leg has neither, the reference price falls back to 0.01, so an OTOCO with a `Market` trigger order is rejected when no quote is available for it. The example above passes: the trigger order buys at 157.97, the profit `Limit` credit is at 198.68 (above it), and the `Stop` credit triggers at 143.06 (below it). An order that breaks these rules is rejected with the preflight error code `invalid_triggered_order_price` and the message `Order price is invalid for this trade.` The same check runs when you replace an order that belongs to an OTOCO with `PUT` or `PATCH` on `/accounts/{account_number}/orders/{id}`. A new trigger order is checked against the existing `orders`; a new order in `orders` is checked against the trigger order's price, or against the current mid price once the trigger order has filled. ## Related - [/reference/orders](/reference/orders) — full order request/response schema - [/reference/errors](/reference/errors) — `400`/`401`/`403`/`404`/`422`/`429`/`5xx` handling (a failed preflight check returns `422`) - [Idempotency & retries](/docs/guides/idempotency-and-retries) and [Rate limits & backoff](/docs/guides/rate-limits-and-backoff) - [Get started](/docs/get-started) and the [MCP server](/docs/sdks-and-tools/mcp-server) ## Related - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Multi-leg spreads](https://developer.tastytrade.com/docs/guides/multi-leg-spreads.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) --- # Order Lifecycle An order in the tastytrade system moves through a sequence of statuses from the moment you submit it until it reaches a final, unchanging state. The statuses can be overwhelming at first, so it helps to group them into three phases: **submission**, **working**, and **terminal**. This page explains what each status means and how orders move between them. Because orders move money, always submit a **dry-run first** to validate buying power, fees, and order construction before placing the live order, and tag each submission with a unique `external-identifier` in the request body. The API does **not** deduplicate retried submissions and there is no idempotency-key header — if a submission's outcome is uncertain (timeout or `5xx`), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for that identifier before resubmitting. See [/docs/guides/idempotency-and-retries](/docs/guides/idempotency-and-retries) and the full request/response shapes in [/reference/orders](/reference/orders). ## Submission phase Statuses: **Received**, **Routed**, **In Flight**, **Contingent** These are orders that have not yet been accepted by any exchange, so they are not "working" yet. - **Received** — typically seen when you submit while the markets are closed. tastytrade has the order and will route it when the market opens. This is one of the first statuses you see. - **Routed** — the order is being submitted to an exchange. - **In Flight** — the order has left tastytrade's system and is awaiting confirmation that the exchange received it. - **Contingent** — the order is dormant, waiting for a related order to update. This applies to complex OTOCO and OTO orders that sit until a triggering order routes them, and to replacement orders waiting for the original order to reach `Cancelled`. An order can also go straight to **Rejected** here — a terminal status (see below) that occurs, for example, when the account lacks sufficient buying power. ## Working phase Statuses: **Live**, **Cancel Requested**, **Replace Requested** An order is "working" once it reaches the exchange and the exchange confirms it. This phase can last milliseconds or, for GTC orders, days or months until you cancel. - **Live** — always the first status after the submission phase. Once live, the order can be canceled or replaced. - **Cancel Requested** — you asked to cancel; the request is at the exchange and tastytrade is awaiting confirmation. On confirmation the order becomes `Cancelled`. - **Replace Requested** — you submitted a replacement for a live (original) order. tastytrade marks the original `Replace Requested` and sends a cancel request for it; meanwhile the replacement sits as `Contingent`. Only when the exchange confirms the original is `Cancelled` does the replacement route. tastytrade never routes the replacement before the original cancels — this gives you cancel-and-replace in a single request. ## Terminal phase Statuses: **Filled**, **Cancelled**, **Rejected**, **Expired**, **Removed**, **Partially Removed** Once an order enters a terminal status it receives no further updates. - **Filled** — the order is fully filled; a position and a trade transaction are created and the account balance updates. - **Cancelled** — the customer canceled the order. - **Rejected** — rejected by tastytrade or the exchange. This can happen in the submission phase (e.g. a non-existent symbol) or the working phase. - **Expired** — usually a day order that did not fill by market close; tastytrade marks it automatically. - **Removed** / **Partially Removed** — an administrator manually removed all or part of the order from the account. ## Status reference | Status | Meaning | Terminal | | --- | --- | --- | | Received | Initial order state | No | | Routed | Order is on its way out of tastytrade's system | No | | In Flight | Order is en route to the exchange | No | | Live | Order is live at the exchange | No | | Cancel Requested | Cancel requested; awaiting a cancel message from the exchange | No | | Replace Requested | Replacement submitted; awaiting a cancel message for the original | No | | Contingent | Awaiting a status update of a related order (OTOCO, OTO, or replacement) | No | | Filled | Order has been fully filled | Yes | | Cancelled | Order is canceled | Yes | | Expired | Order has expired; usually a day order that did not fill by close | Yes | | Rejected | Rejected by tastytrade or the exchange | Yes | | Removed | Administrator manually removed this order | Yes | | Partially Removed | Administrator manually removed part of this order | Yes | ## Partial fills tastytrade marks an order `Filled` as soon as possible, even if every individual fill is not yet processed. If you read the order and its status is `Filled` but one or more legs are missing fills, you simply hit the API while the system was still processing — expect this and re-fetch after a brief delay. Fills usually finish processing within milliseconds. ## Example transitions Immediate fill: ``` Received -> Routed -> In Flight -> Live -> Filled ``` Canceled by customer: ``` Received -> Routed -> In Flight -> Live -> Cancel Requested -> Cancelled ``` Expired day order: ``` Received -> Routed -> In Flight -> Live -> Expired ``` Rejected immediately: ``` Received -> Rejected ``` ## Related - [/reference/orders](/reference/orders) — order endpoints, fields, and the status field. - [/docs/guides/idempotency-and-retries](/docs/guides/idempotency-and-retries) — safe retries with `external-identifier`. - [/docs/guides/rate-limits-and-backoff](/docs/guides/rate-limits-and-backoff) — backing off on `429`/`5xx`. ## Related - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) --- # Positions & Balances Balances and positions answer two related questions about an account: *what is it worth right now*, and *what does it hold*. This page explains the concepts behind both so you can read the API responses confidently. For the full endpoint contracts, parameters, and every field, see [/reference/balances-and-positions](/reference/balances-and-positions). All requests go to the sandbox base URL `https://api.cert.tastyworks.com` or production `https://api.tastyworks.com`, require an OAuth access token (15-minute lifetime via `POST /oauth/token`), and must send a `User-Agent: product/version` header. JSON keys are dasherized (for example `net-liquidating-value`). See [/docs/get-started](/docs/get-started) for authentication setup. ## Balances Each account has a single balance object describing its monetary values. Fetch it with: ```http GET /accounts/{account_number}/balances ``` Key fields: | Field | Meaning | | --- | --- | | `cash-balance` | Settled cash in the account. May be positive or negative. | | `net-liquidating-value` | Total current value of the account — roughly the cash you would end up with if you closed every position. | | `equity-buying-power` | Funds available to open equity positions. | | `derivative-buying-power` | Funds available to open options (derivative) positions. | | `day-trading-buying-power` | Funds available for day trades. | | `maintenance-requirement` | Margin the account must maintain against current positions. | | `cash-available-to-withdraw` | Cash that can be withdrawn right now. | | `pending-cash` / `pending-cash-effect` | Cash mid-transfer that has not cleared. `Credit` is an incoming deposit; `Debit` is an outgoing withdrawal. Usually `0.0`. | Position values are broken out by instrument type and side, for example `long-equity-value`, `short-equity-value`, `long-derivative-value` (options), `long-futures-value`, and `long-cryptocurrency-value`. Margin fields such as `margin-equity`, `reg-t-margin-requirement`, and `futures-margin-requirement` describe the account's margin state. A **balance snapshot** is captured twice daily (morning and after the equities close). Fetch one with `GET /accounts/{account_number}/balance-snapshots`. The `time-of-day` parameter (`BOD` for beginning of day, `EOD` for end of day) is required per the API spec; optionally pass `snapshot-date` to select a specific date. ## Positions A position records a single holding. Fetch all open positions with: ```http GET /accounts/{account_number}/positions ``` ```json { "data": { "items": [ { "account-number": "5WT00000", "symbol": "AAPL", "instrument-type": "Equity", "underlying-symbol": "AAPL", "quantity": "100", "quantity-direction": "Long", "average-open-price": "288.7", "close-price": "282.48", "multiplier": 1, "realized-day-gain": "0.0", "realized-today": "0.0" } ] }, "context": "/accounts/5WT00000/positions" } ``` (Some position fields omitted for brevity.) Important fields: - `symbol` / `underlying-symbol` — tastytrade symbology covers equities, OCC options, futures (`/ESZ4`), future options (`./ESZ4 EW3U4 240920P5650`), and crypto pairs. - `quantity` and `quantity-direction` (`Long`, `Short`, `Zero`). A quantity of 0 is closed; closed positions are purged overnight. - `average-open-price` — running average open price, the cost basis for unrealized gain since open. - `multiplier` — notional units delivered on exercise/assignment (equity options are typically `100`). - `realized-today` and `realized-day-gain` — realized profit/loss since open and for the current day, paired with `*-effect` and `*-date` fields. Ignore the value if its date is not today. Equity option and futures positions also carry an `expires-at` timestamp. ## Profit / loss and mark The API does not return a live profit/loss figure. You compute it using **mark** (current value of one unit) against a cost basis: ``` Long positions: (mark - cost-basis) * quantity * multiplier Short positions: (cost-basis - mark) * quantity * multiplier ``` Use `average-open-price` as the cost basis for unrealized gain since open; note the operands flip for short positions. Mark is best taken from live quote data — for long positions use the bid, for short positions the ask, or the mid `(bid + ask) / 2`. The positions endpoint can also return point-in-time `mark` and `mark-price` fields when called with `include-marks=true` (off by default; can decrease performance). For live P/L, subscribe via streaming market data and recalculate as quotes change (throttling to about once per second is sensible). ## Calculating net liquidating value The `net-liquidating-value` returned by `GET /accounts/{account_number}/balances` is the authoritative figure. This section explains a client-side estimate you can recompute between balance fetches as streamed quotes move. The estimate can differ from the API figure, so use the API value as the source of truth. Start with the current value of each position: ``` current value = mark * quantity * multiplier * direction ``` Take `direction` from the position's `quantity-direction`: `1` for `Long` and `-1` for `Short`. A `Zero` position has a `quantity` of 0, so it adds 0 whichever direction you apply. Use `quantity` as the API returns it. The API reference does not say whether `quantity` is signed, so check a short position in your own account before relying on the sign; if a short position's `quantity` already comes back negative, do not apply `direction` a second time. Add up the position values, then add cash: ``` net liq estimate = (sum of position current values) + cash-balance ``` `pending-cash` is cash that has not cleared yet and is usually `0.0`. The estimate ignores it. ### Scope and limits - The formula is for equities and equity options. Futures, futures options, cryptocurrency and other instruments are not covered here. - `mark` is the price you supply. The example below uses a given mark. For live marks, use market data as described in the Profit/loss section above (or the positions endpoint with `include-marks=true`). - How the balances service itself computes `net-liquidating-value`, including how it treats `pending-cash`, is not covered here. If your figure has to match the account's value exactly, use the `net-liquidating-value` the API returns. ### Worked example Say the account is long 100 shares of ABC with a mark of $100, short 100 shares of XYZ with a mark of $50, and holds $1,000 cash. | Position | Calculation | Current value | | ----------- | -------------------- | ------------- | | ABC (long) | $100 * 100 * 1 * 1 | $10,000 | | XYZ (short) | $50 * 100 * 1 * -1 | -$5,000 | The estimate is $10,000 - $5,000 + $1,000 = **$6,000**. Throttle recalculation to about once per second when you drive it from streaming quotes. ## Related topics - Money-moving (orders) is separate from these read-only endpoints. Always submit a dry-run first and set a unique client-supplied `external-identifier` on the order. The API does not deduplicate retried submissions (there is no idempotency-key header), so on an uncertain outcome check your live orders for that identifier before resubmitting — see [/docs/guides/idempotency-and-retries](/docs/guides/idempotency-and-retries). - Error responses use standard codes (400/401/403/404/422/429/5xx); see [/reference/errors](/reference/errors). - Back off on `429` per [/docs/guides/rate-limits-and-backoff](/docs/guides/rate-limits-and-backoff). - The [MCP server](/docs/sdks-and-tools/mcp-server) exposes balances and positions to agents. ## Related - [Margin & Risk](https://developer.tastytrade.com/docs/concepts/margin-and-risk.md) - [Stream market data](https://developer.tastytrade.com/docs/guides/stream-market-data.md) - [Instruments & Symbology](https://developer.tastytrade.com/docs/concepts/instruments-and-symbology.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) --- # Market Data tastytrade exposes REST endpoints for fetching market data. These endpoints are available to funded account holders, and in production they return real-time quotes — there is no REST endpoint for delayed quotes. For continuous, low-latency updates, prefer the streaming feed over polling (see below). All requests use the standard base URLs (sandbox `https://api.cert.tastyworks.com`, production `https://api.tastyworks.com`) and require the `User-Agent: /` header plus a valid OAuth access token. See [Get Started](/docs/get-started) for authentication details. The sandbox does not serve these routes: `/market-data` and `/market-metrics` return HTTP 502 there. See [Sandbox](/docs/sandbox). ## Fetch quotes by instrument type The core endpoint is `GET /market-data/by-type`. It fetches quotes for several securities at once. You pass each instrument type as a query-string parameter whose value is a comma-delimited list of symbols. The parameter key is the security type and the value is the list of symbols for that type. | Parameter | Description | Example symbol | | --- | --- | --- | | `cryptocurrency` | Cryptocurrency pairs | `BTC/USD` | | `equity` | Equities | `AAPL` | | `equity-option` | OCC equity options | `SPY 250428P00355000` | | `index` | Indices | `SPX` | | `future` | Futures | `/CLM5` | | `future-option` | Future options | `./MESU5EX3M5 250620C6450` | Symbols follow tastytrade symbology: a leading `/` for futures, `./` for future options, OCC format for equity options, and `BASE/QUOTE` pairs for crypto. You can combine multiple instrument-type parameters in a single request. ```bash curl -s "https://api.tastyworks.com/market-data/by-type?equity=AAPL,TSLA&cryptocurrency=BTC/USD" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" ``` ### Combined symbol limit The total number of symbols across all instrument-type parameters in one request is capped at 100. Count every symbol in every parameter toward that limit — e.g. 60 equities plus 40 future options reaches the 100-symbol cap. If you need quotes for more symbols, split them across multiple requests, or switch to streaming. ## Response fields The response wraps a list of quote objects under `data.items`. JSON keys are dasherized. Each item carries the symbol, its `instrument-type`, and an `updated-at` timestamp, along with pricing and session fields: ```json { "data": { "items": [ { "symbol": "AAPL", "instrument-type": "Equity", "updated-at": "2025-04-29T21:33:25.535Z", "bid": "210.55", "bid-size": "2.0", "ask": "210.6", "ask-size": "1.0", "mid": "210.575", "mark": "210.55", "last": "210.511", "last-mkt": "211.21", "open": "208.693", "day-high-price": "212.24", "day-low-price": "208.37", "close": "211.21", "prev-close": "210.14", "is-trading-halted": false, "year-low-price": "169.11", "year-high-price": "260.1", "volume": "35348839.0" } ] }, "pagination": null } ``` Common fields include `bid`/`ask` (and their `bid-size`/`ask-size`), `mid` (the midpoint), `mark`, `last` (last traded price) and `last-mkt` (last price from the regular/primary market), session prices (`open`, `day-high-price`, `day-low-price`, `close`, `prev-close`), 52-week range (`year-low-price`, `year-high-price`), `volume`, and trading-halt flags (`is-trading-halted`). Some instrument types add fields — equities may include `beta`, `dividend-amount`, `dividend-frequency`, and `low-limit-price`/`high-limit-price`. See the [Market Data reference](/reference/market-data) for the full field list per instrument type. ## Prefer streaming over polling REST quotes are best for one-off snapshots. For live data, the DXLink streaming feed is strongly preferred — it pushes updates as the market moves instead of forcing you to poll, which avoids hitting [rate limits](/docs/guides/rate-limits-and-backoff) and stale data. See [Streaming](/docs/concepts/streaming) for setup. ## Errors This endpoint documents `400`, `401`, `403`, and `429` responses; other standard HTTP codes may occur API-wide. A `429` means you should back off and retry; see [Rate Limits and Backoff](/docs/guides/rate-limits-and-backoff). For the API-wide catalog, see [/reference/errors](/reference/errors). Market data is read-only and does not move money. For order placement, dry-run first and supply a unique `external-identifier` in the request body; see [Idempotency and Retries](/docs/guides/idempotency-and-retries). ## Related - [Streaming](https://developer.tastytrade.com/docs/concepts/streaming.md) - [Instruments & Symbology](https://developer.tastytrade.com/docs/concepts/instruments-and-symbology.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [Stream market data](https://developer.tastytrade.com/docs/guides/stream-market-data.md) --- # Streaming tastytrade exposes two independent WebSocket streamers. They serve different purposes, use different tokens, and connect to different hosts: - The **DXLink market-data streamer** pushes live quotes, trades, Greeks, and candles from tastytrade's quote provider (dxFeed). - The **account streamer** pushes one-directional notifications about your account state (orders, balances, positions) plus non-account data: public watchlists and user-level quote alerts. Both let you subscribe to real-time updates instead of polling REST endpoints. Streaming is for _staying in sync_; the REST API in `/reference` remains the source of truth and the only way to _take action_ (place orders, etc.). ## DXLink market-data streamer ### 1. Get an API quote token Request a token with `GET /api-quote-tokens`. The token is tied to the customer identified by your OAuth access token, and the response includes the `dxlink-url` to connect to: ```json { "data": { "token": "", "dxlink-url": "wss://dxlink.example.com/realtime", "level": "api" }, "context": "/api-quote-tokens" } ``` **API quote tokens expire after 24 hours** — refresh before they lapse. You must be a fully onboarded tastytrade customer; a username/password-only registration is rejected with `quote_streamer.customer_not_found_error`. ### 2. Connect and exchange messages Open a WebSocket to the returned `dxlink-url`. Message order matters; the high-level handshake is: 1. `SETUP` — initiate the connection (negotiate version and keepalive timeout). 2. `AUTH` — after the server sends `AUTH_STATE` with `state: UNAUTHORIZED`, authorize with your API quote token. 3. `CHANNEL_REQUEST` — open a channel (a virtual sub-connection; use separate channels to organize subscriptions, e.g. equities vs. futures). 4. `FEED_SETUP` — configure which event fields to receive on the channel. 5. `FEED_SUBSCRIPTION` — subscribe to (or `remove`) events for one or more symbols. 6. `KEEPALIVE` — send periodically to hold the connection open. A `SETUP` plus `AUTH` exchange looks like this: ```json { "type": "SETUP", "channel": 0, "version": "0.1-DXF-JS/0.3.0", "keepaliveTimeout": 60, "acceptKeepaliveTimeout": 60 } { "type": "AUTH", "channel": 0, "token": "" } ``` A channel configured for `COMPACT` data (requested via `FEED_SETUP`'s `acceptDataFormat`) delivers events as positional arrays rather than verbose objects: ```json { "type": "FEED_SUBSCRIPTION", "channel": 3, "reset": true, "add": [ { "type": "Quote", "symbol": "SPY" }, { "type": "Trade", "symbol": "SPY" } ] } ``` ```json { "type": "FEED_DATA", "channel": 3, "data": ["Trade", ["Trade", "SPY", 559.36, 13743299, 100.0]] } ``` Subscriptions are capped, and the caps shape how you should batch them: 5 concurrent sessions, 25,000 subscriptions per session, 100 each for `Candle`, `Order` and `Series`, and 10,000 subscription changes per minute. Full detail in [Streaming rate limits](/docs/guides/rate-limits-and-backoff#streaming-rate-limits). Event types defined by dxFeed's DXLink protocol include **Quote**, **Trade**, **Summary**, **Greeks**, **TimeAndSale**, **Profile**, and **Candle**; which types a given feed returns depends on the feed and the token you connect with. Candle events return historical aggregates (open/high/low/close) — you supply a period and type in the symbol (for example `AAPL{=5m}`) plus a `fromTime` Unix-epoch timestamp. ### Keepalive and quiet feeds If DXLink does not receive a keepalive within its 60-second timeout, it closes the connection. Sending `KEEPALIVE` every ~30 seconds keeps it open indefinitely: ```json { "type": "KEEPALIVE", "channel": 0 } ``` DXLink only publishes events as they occur. A connected, heartbeating socket that receives nothing usually means the symbol simply has no trading activity — that is normal, not a bug. ### Symbology You must subscribe using DXLink-formatted symbols. tastytrade provides these on instrument responses in the `streamer-symbol` field — for example a futures contract `/6AM3` exposes `streamer-symbol: "/6AM23:XCME"`. The same field is available across the instruments endpoints (`GET /instruments/equities/{symbol}`, `GET /instruments/futures`, `GET /instruments/cryptocurrencies`, `GET /option-chains/{symbol}`, `GET /futures-option-chains/{symbol}`). Prefer it over hand-building symbols. For more on tastytrade symbology (`/` futures, `./` future options, OCC options, crypto pairs), see `/reference`. ## Account streamer The account streamer is a one-directional WebSocket that publishes notifications when your account data changes. Instead of re-fetching an order to learn it went from `Routed` to `Filled`, you receive a push message as the status changes. ### Hosts | Environment | WebSocket host | | ----------- | ------------------------------------ | | Sandbox | `wss://streamer.cert.tastyworks.com` | | Production | `wss://streamer.tastyworks.com` | These pair with the REST hosts `https://api.cert.tastyworks.com` (sandbox) and `https://api.tastyworks.com` (production). ### Authentication Every message includes an `auth-token` — your tastytrade OAuth access token, the same value you send in the `Authorization` header for REST calls. Access tokens last 15 minutes (mint a fresh one with `POST /oauth/token` — see [Get started](/docs/get-started) for the auth flow), so refresh and re-authenticate over the long-lived socket as needed. ### Connect, then heartbeat Perform these steps in order — if you heartbeat before connecting you may get a `not implemented` error: 1. Open the WebSocket connection. 2. Send a `connect` message to subscribe to account updates. 3. Send `heartbeat` messages on a 2s–1m interval. ```json { "action": "connect", "value": ["5WT00000", "5WT00001"], "auth-token": "", "request-id": 2 } ``` ```json { "action": "heartbeat", "auth-token": "", "request-id": 1 } ``` The optional `request-id` is echoed back in the server's response so you can correlate messages. Other actions include `public-watchlists-subscribe` and `quote-alerts-subscribe` (note: quote alerts are scoped to the user, not an account). ### Receiving notifications Notifications use the same JSON object representations as the REST API and always contain the **full** object — never a partial or differential update. Each message carries a `type` and a `data` payload: ```json { "type": "Order", "data": { "id": 1, "account-number": "5WT00000", "status": "Live", "underlying-symbol": "AAPL", "ext-client-order-id": "67890" }, "timestamp": 1688595114405 } ``` Note the dasherized JSON keys (`account-number`, `ext-client-order-id`), consistent with the rest of the API. ## Streaming and orders The account streamer reports order state — it does not place orders. Submit orders over REST, **dry-run first** (validate against `POST /accounts/{account_number}/orders/dry-run`), then send the live order with your own unique `external-identifier` so _you_ can recognize an order you already submitted — the server does **not** deduplicate retries, and there is no idempotency-key header. On an uncertain outcome (timeout, `5xx`), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for that identifier before resubmitting. See [Idempotency & retries](/docs/guides/idempotency-and-retries). You then watch the streamer for `Order` notifications as the status advances. ## Operational notes - Always send the `User-Agent: product/version` header on the REST calls that mint your tokens. - Reconnect with backoff on drops; respect the 60-second DXLink keepalive timeout and the account-streamer heartbeat window. See [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). - Token errors (`401`/`403`) and other HTTP error codes (`400`/`404`/`422`/`429`/`5xx`) on the token endpoints are documented in [/reference/errors](/reference/errors). - For an end-to-end client that wraps both streamers, see [MCP Server](/docs/sdks-and-tools/mcp-server). ## Machine-readable spec Both streamers are described in an AsyncAPI 2.6 document — download it as [JSON](/asyncapi/tastytrade-streaming.asyncapi.json) or [YAML](/asyncapi/tastytrade-streaming.asyncapi.yaml). ## Related - [Stream market data](https://developer.tastytrade.com/docs/guides/stream-market-data.md) - [Stream account updates](https://developer.tastytrade.com/docs/guides/stream-account-updates.md) - [Market Data](https://developer.tastytrade.com/docs/concepts/market-data.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) --- # Margin & Risk Before an order can rest on the exchange, tastytrade evaluates whether your account can support it. This page explains the three things you read most often when reasoning about that: an account's **current margin requirements**, the **margin dry-run** that estimates an order's impact before you commit, and the **trading status** that gates which features and order types you may use. All requests go to the sandbox base URL `https://api.cert.tastyworks.com` or production `https://api.tastyworks.com`, carry a `User-Agent: product/version` header, and authenticate with a short-lived (15-minute) OAuth access token from `POST /oauth/token`. JSON keys are dasherized (for example `margin-requirement`, `day-trade-count`). Monetary fields pair a value with an `*-effect` field of `Debit`, `Credit`, or `None` that tells you the direction. ## Current margin requirements `GET /margin/accounts/{account_number}/requirements` returns your account's margin picture, grouped by underlying symbol. The top level summarizes the whole account — `margin-requirement`, `maintenance-requirement`, `margin-equity`, `maintenance-excess`, and buying-power figures (including separate `reg-t-*` values), each with its effect — and `margin-calculation-type` (for example `Reg T`). Each entry in `groups` is one underlying, with its own requirement totals, `buying-power`, and the risk shocks, plus a nested inner `groups` array of margin-strategy groups (for example `LONG_UNDERLYING`) — each of those carries `includes-working-order` and the position legs under `position-entries`. The per-underlying `price-increase-percent` and `price-decrease-percent` are the **risk parameters**: the price shocks (here `0.5` and `-0.5`) used to stress that position when computing its requirement. `includes-working-order` flags whether unfilled orders are already factored into a strategy group's requirement. ```bash curl "https://api.tastyworks.com/margin/accounts/5WT00001/requirements" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" ``` ## The margin dry-run The dry-run answers "what would this order do to my margin?" **without placing it.** Always estimate impact this way before sending a real order — it is the margin-focused complement to the order dry-run. `POST /margin/accounts/{account_number}/dry-run` takes the same body you would send to submit an order, plus three extra attributes: `account-number`, `underlying-symbol`, and `underlying-instrument-type` (one of `Equity`, `Equity Option`, `Future`, `Future Option`, `Cryptocurrency`). Symbols follow tastytrade symbology — OCC for equity options, `/` for futures, `./` for future options, and pair notation for crypto. ```json { "account-number": "5WT00001", "time-in-force": "Day", "order-type": "Limit", "price": "186.99", "price-effect": "Debit", "underlying-symbol": "AAPL", "underlying-instrument-type": "Equity", "legs": [ { "instrument-type": "Equity", "symbol": "AAPL", "quantity": 1, "action": "Buy to Open" } ] } ``` The response compares your account before and after. Read `change-in-margin-requirement`, `change-in-buying-power`, and the `current-buying-power` versus `new-buying-power` pair (each with its effect) for the headline impact. `isolated-order-margin-requirement` and `is-spread` describe the order on its own, while `last-results`, `base-results`, and `new-order-results` give the full per-underlying breakdown, including `buying-power-impact`, `working-margin`, `position-margin`, and the underlying price `marks` used in the calculation. A dry-run never creates an order, so it is safe to repeat. When you do place the real order, send it dry-run-first and set a unique `external-identifier` in the request body (there is no idempotency-key header, and the API does not deduplicate retried submissions). If the outcome of a submit is uncertain — a timeout or `5xx` — check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), for that identifier before resubmitting — see [/docs/guides/idempotency-and-retries](/docs/guides/idempotency-and-retries). ## Trading status `GET /accounts/{account_number}/trading-status` reports whether and how an account may trade. If `is-closed` or `is-frozen` is true, trading is blocked; if `is-closing-only` is true, only closing trades are allowed account-wide, while `is-cryptocurrency-closing-only` and `is-futures-closing-only` apply the same restriction to crypto and futures respectively. `is-risk-reducing-only` similarly restricts you to de-risking activity. Key fields: | Field | Meaning | | --- | --- | | `options-level` | Highest options strategy tier permitted (for example `No Restrictions`). | | `is-pattern-day-trader` | Whether PDT rules apply to the account. | | `day-trade-count` | Live count of day trades used, updated throughout the day. | | `is-in-margin-call` / `is-in-day-trade-equity-maintenance-call` | Outstanding margin or day-trade maintenance calls. | | `is-cryptocurrency-enabled`, `is-futures-enabled`, `short-calls-enabled` | Per-feature toggles for what the account may trade. | | `equities-margin-calculation-type` | How equities margin is computed (for example `Reg T`). | | `futures-margin-rate-multiplier` | Intraday futures margin multiplier — `0` means no intraday futures margin; when set, eligible intraday futures positions are margined at the standard requirement divided by this value. | Check trading status before building order flows so you surface restrictions up front rather than discovering them as a rejected order. ## Errors Expect standard HTTP codes: `400`/`422` for malformed or invalid input, `401` for an expired or missing token, `403` when a restriction blocks the action, `404` for an unknown account, `429` when rate-limited, and `5xx` for server-side issues. See [/reference/errors](/reference/errors) and [/docs/guides/rate-limits-and-backoff](/docs/guides/rate-limits-and-backoff). ## Related - [/reference/margin-requirements](/reference/margin-requirements) — full margin and dry-run schemas. - [/reference/account-status](/reference/account-status) — full trading-status schema. - [/docs/get-started](/docs/get-started) — authentication and your first request. - [/docs/sdks-and-tools/mcp-server](/docs/sdks-and-tools/mcp-server) — query margin and status from the MCP server. ## Related - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Positions & Balances](https://developer.tastytrade.com/docs/concepts/positions-and-balances.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) --- # Idempotency & retries Retrying a failed request must never place a duplicate order. tastytrade does **not** provide a generic `Idempotency-Key` header, so safe retries are a client-side discipline. This guide is the golden path. ## The short version - **Reads (`GET`)** are safe to retry freely. - **Order placement is _not_ idempotent.** The API does not deduplicate retried submissions — make retries safe with a unique **`external-identifier`** + a **status check before resubmitting**. - **Always dry-run first** (see [Place an equity order](/docs/guides/place-an-equity-order)). - Back off exponentially on `429`/`5xx`/network errors — see [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). ## `external-identifier` — your correlation handle Every order submission can carry an **`external-identifier`**: a client-generated id you set in the request body (it is a field on the POST/PUT order schemas) that tastytrade echoes back on the order object. It is **not** a server-enforced idempotency key — the API does not deduplicate submissions, so a repeated id does not stop a second order from being placed — but it lets *you* recognize an order you already submitted. Generate a **unique** `external-identifier` per intended order (e.g. a UUID) and keep it until you've confirmed the order's terminal state. Don't confuse it with **`ext-client-order-id`**: that is a **system-populated, read-only** field that appears on order responses and account-streamer messages. It is not a request field or a header — never send it yourself. ## Safe order-placement flow 1. Generate a unique `external-identifier` for the order you intend to place. 2. **Dry-run** the order; only proceed if it returns no errors. 3. **Submit** the order with your `external-identifier` in the request body. 4. If you get a clear success or a clear rejection — you're done. 5. If the response is **uncertain** (timeout, network drop, `5xx`): **do not blindly resubmit.** First **query your orders** — `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/accounts/{account_number}/orders/live` (see [/reference/orders](/reference/orders)) — and check whether an order with your `external-identifier` already exists. - Exists → it went through; do not resubmit. - Absent → safe to resubmit (reuse the same `external-identifier`). ## Cancel / replace `cancel` and `replace` act on a specific order id. Before retrying one, re-fetch the order and branch on its current `status` (it may already be `Filled`, `Cancelled`, or in a `…Requested` state) rather than firing the same mutation again. ## Backoff Use exponential backoff with jitter, and cap retries: | Response | Retry? | | -------- | ------ | | `2xx` | No (done) | | `4xx` (except `429`) | No — fix the request (see the [error reference](/reference/errors)) | | `429` | Yes, after backoff — [Rate limits & backoff](/docs/guides/rate-limits-and-backoff) | | `5xx` / network | Yes, after backoff — and for orders, do the status check above first | ## Using the MCP server If you drive trading through the [tastytrade MCP server](/docs/sdks-and-tools/mcp-server), duplicate placement is prevented at that layer too: every order requires a single-use, args-bound confirmation token issued by a prior dry-run, so a replayed call fails loudly instead of placing twice. ## Related - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) - [MCP Server](https://developer.tastytrade.com/docs/sdks-and-tools/mcp-server.md) --- # Rate limits & backoff On the REST side tastytrade throttles by **reasonable thresholds** rather than a published per-endpoint quota — the documented `429` responses carry no rate-limit headers, so treat the bare status as the only signal. The contract is simple: don't hammer the API, back off when told, and prefer streaming over polling. **Streaming is different**: the market-data streamer has hard, published caps. Those are exact numbers, and exceeding them fails rather than throttles. See [Streaming rate limits](#streaming-rate-limits). ## What you'll hit - **`429 Too Many Requests`** — you sent a high volume of requests in a short window, exceeding reasonable thresholds. See [error reference → 429](/reference/errors#429). - **IP block (~8 hours)** — too many **failed logins** in a short period gets your IP blocked outright (a brute-force protection). Requests then time out. Contact `api.support@tastytrade.com` to be unblocked. ## Backoff On `429` (and on `5xx`/network errors), retry with **exponential backoff + jitter**, and cap the number of attempts. Do **not** tight-loop retries — that's what triggers the threshold in the first place. For order placement, combine backoff with the status check in [Idempotency & retries](/docs/guides/idempotency-and-retries). ## Streaming rate limits Unlike the REST thresholds, the DXLink market-data streamer enforces explicit limits: | Limit | Value | | --------------------------------------------------------- | ------------------- | | Total concurrent sessions | **5** | | Subscriptions per session | **25,000** | | Per-event subscription cap, `Candle` / `Order` / `Series` | **100** each | | Subscription change rate | **10,000 / minute** | Two of these catch people out. The **per-event cap of 100** applies to `Candle`, `Order` and `Series` specifically, so a client that happily holds thousands of `Quote` subscriptions will still fail at the 101st `Candle`. And the **change rate** is a rate, not a total: churning subscriptions symbol-by-symbol as a user scrolls a watchlist can exhaust 10,000/minute while the subscription count stays small. Batch subscription changes and unsubscribe in groups rather than per-symbol. The 5-session limit is per set of credentials, so a client that opens a session per browser tab or per worker will hit it before it hits anything else. Share one streamer connection and fan out internally. ## Reduce load (the real fix) - **Stream, don't poll.** For live quotes and account updates use the **DXLink** market-data streamer and the account streamer instead of polling REST. (Get a quote token first; see the streaming docs.) - **Batch.** Endpoints that accept many symbols at once — e.g. the [market-data quote snapshot](/docs/concepts/market-data) (`GET /market-data/by-type`, **up to 100 symbols** across all instrument-type parameters) — let you replace many calls with one. - **Cache** slow-changing data (instrument definitions, option chains, session calendars) instead of re-fetching per request. ## A sensible client-side guideline If you want a client-side ceiling to code against, the **tastytrade MCP server** charges each call against tastytrade's own published per-second, per-endpoint ceilings plus a **50/sec global cap**. Mirroring that — a per-endpoint ceiling with a global cap, counted once per call — is a reasonable default for any client, and it is stricter than the REST thresholds in normal use. Combined with streaming for anything live, and caching for anything slow-changing, that is usually enough to never see a `429`. ## Related - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) - [Streaming](https://developer.tastytrade.com/docs/concepts/streaming.md) - [FAQ](https://developer.tastytrade.com/docs/faq.md) --- # 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](/docs/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: ```json { "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](/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: ```bash curl -X POST "https://api.cert.tastyworks.com/accounts/{account_number}/orders/dry-run" \ -H "Authorization: Bearer " \ -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](/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. ```bash curl -X POST "https://api.cert.tastyworks.com/accounts/{account_number}/orders" \ -H "Authorization: Bearer " \ -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` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), 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](/docs/guides/idempotency-and-retries) for the full pattern. For `429` responses, back off per [Rate limits and backoff](/docs/guides/rate-limits-and-backoff). ## Next steps - Browse the full orders API at [/reference/orders](/reference/orders). - Explore all endpoints in the [API reference](/reference). - Place orders conversationally with the [MCP server](/docs/sdks-and-tools/mcp-server). ## Related - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Multi-leg spreads](https://developer.tastytrade.com/docs/guides/multi-leg-spreads.md) --- # Multi-leg spreads A spread is a single order with more than one leg. Each leg is one instrument, with its own action, quantity, and symbol, and the whole order shares one `order-type`, `price`, and `price-effect`. This guide shows how to assemble the `legs` array for common option spreads (verticals, iron condors, strangles) and submit them. Equity Option and Future Option orders can have up to **4 legs**. (Equity, Future, and Cryptocurrency orders are limited to 1 leg.) See [Orders and order types](/docs/concepts/orders-and-order-types) for the full order model. ## Structure each leg Every option leg needs four fields: | Leg attribute | Meaning | | --- | --- | | `instrument-type` | `Equity Option` for equity option spreads, `Future Option` for futures option spreads. | | `symbol` | The OCC option symbol, e.g. `AAPL 221118C00157500`. Fetch symbols from the option chain (see below). | | `quantity` | A whole number of contracts. Must be positive. | | `action` | `Buy to Open` / `Sell to Open` (opening) or `Buy to Close` / `Sell to Close` (closing). | Each leg must use a distinct `symbol` — an order with two legs sharing one symbol is rejected. Find option symbols via the option chain, e.g. `GET /option-chains/{symbol}/nested`, which groups strikes under each expiration with `call` and `put` symbols. See the [instruments reference](/reference/instruments) for the full set of chain endpoints. The order-level `price` is the **net** debit or credit across all legs. `price-effect` is `Debit` (you pay) or `Credit` (you receive). A net-credit vertical or condor uses `Credit`; a net-debit spread uses `Debit`. ## Example: vertical spread A bear call vertical sells a lower strike and buys a higher strike for a net credit. Both legs share the same expiration and quantity. ```json { "time-in-force": "Day", "order-type": "Limit", "price": "0.85", "price-effect": "Credit", "legs": [ { "instrument-type": "Equity Option", "symbol": "AAPL 221118C00155000", "quantity": 1, "action": "Sell to Open" }, { "instrument-type": "Equity Option", "symbol": "AAPL 221118C00157500", "quantity": 1, "action": "Buy to Open" } ] } ``` ## Example: iron condor An iron condor is four legs: a put spread below the price and a call spread above it. The defining (short) strikes sit inside the protective (long) strikes, and the order takes a net credit. ```json { "source": "my-api-code", "order-type": "Limit", "time-in-force": "Day", "price": "1.51", "price-effect": "Credit", "legs": [ { "instrument-type": "Equity Option", "symbol": "TSLA 230714P00210000", "action": "Buy to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714P00215000", "action": "Sell to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714C00282500", "action": "Sell to Open", "quantity": 1 }, { "instrument-type": "Equity Option", "symbol": "TSLA 230714C00290000", "action": "Buy to Open", "quantity": 1 } ] } ``` ## Example: strangle A strangle follows the same idea with two legs instead of four — sell (or buy) an out-of-the-money put and an out-of-the-money call at the same expiration. ## Dry-run first, then submit Always validate a multi-leg order before routing it. POST the same JSON to the dry-run endpoint, inspect the `buying-power-effect`, `fee-calculation`, and any `warnings`, then submit the live order only if it looks right. ```http POST /accounts/{account_number}/orders/dry-run Authorization: Bearer ACCESS_TOKEN User-Agent: my-app/1.0.0 Content-Type: application/json ``` The live endpoint is `POST /accounts/{account_number}/orders`. Send your 15-minute OAuth access token from `POST /oauth/token` in the `Authorization` header, and always include a `User-Agent: product/version` header. The API does not deduplicate retried submissions and there is no idempotency-key header, so make retries safe yourself: dry-run first, submit with a unique `external-identifier` (the order response echoes it back), and if the outcome is uncertain (timeout or 5xx), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for that identifier before resubmitting. See [Idempotency and retries](/docs/guides/idempotency-and-retries) and [Rate limits and backoff](/docs/guides/rate-limits-and-backoff). A failed validation returns `422` with an error payload listing each problem (for example `cant_buy_for_credit` when buying for a credit). Other HTTP errors follow the usual `400/401/403/404/429/5xx` codes — see [Errors](/reference/errors). See the full request and response schema in the [orders reference](/reference/orders). New to the API? Start with [Get started](/docs/get-started). ## Related - [Orders & Order Types](https://developer.tastytrade.com/docs/concepts/orders-and-order-types.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) --- # Error handling This is a real money API. Handle errors deterministically: read the envelope, branch on the machine code (never the prose message), then map the HTTP status to a fix. For the full catalog of codes and remediations, see [`/reference/errors`](/reference/errors). ## Read the error envelope Failed responses carry a JSON envelope. Branch on `error.code` (stable, machine-readable) and surface `error.message` for humans — but never parse or pattern-match the message text, which can change. ```json { "error": { "code": "invalid_credentials", "message": "Login failed." } } ``` ```bash # Branch on the code, not the message ($resp holds the captured response body) code=$(jq -r '.error.code' <<<"$resp") case "$code" in unauthorized|invalid_credentials) echo "re-authenticate" ;; *) echo "see /reference/errors#$code" ;; esac ``` Map any code you receive to its remediation at `/reference/errors#` (for example, [`/reference/errors#422`](/reference/errors#422)). ## Branch by HTTP status Use the status for the broad recovery strategy; use `error.code` for the specific fix. | Status | Meaning | What to do | | --- | --- | --- | | 400 | Bad Request | Validate the body against the endpoint schema. JSON keys are dasherized (e.g. `account-number`). Do not retry unchanged. | | 401 | Unauthorized | Re-authenticate. Access tokens last 15 minutes — refresh via `POST /oauth/token`. Also check the `User-Agent` gotcha below. | | 403 | Forbidden | Authenticated but not permitted. Check your OAuth scopes and the account's authority level. Do not retry. | | 404 | Not Found | Verify the path and identifiers (account number, symbol, order id), and confirm the environment (sandbox vs production). Do not retry. | | 422 | Unprocessable Entity | The action is invalid in context. Read `error.message`, fix the cause, then resubmit. For orders, dry-run first. | | 429 | Too Many Requests | Back off and reduce rate — see below. | | 5xx | Server Error | Transient on tastytrade's side. Retry with backoff. | ## The User-Agent 401 gotcha tastytrade requires a `User-Agent` header in the format `product/version` (for example, `my-app/1.0`). If it is missing or malformed you get a 401 — even when your token is valid — and the body is an HTML nginx page rather than the JSON envelope: ```http HTTP/1.1 401 Authorization Required Content-Type: text/html ``` If you see a 401 with an HTML body and no `error.code`, set a valid `User-Agent` and retry. See [`/docs/get-started`](/docs/get-started). A 401 with `error.code` of `invalid_credentials` usually means you sent one environment's credentials to the other — sandbox `https://api.cert.tastyworks.com` and production `https://api.tastyworks.com` have separate credentials. ## Retry and backoff (429 / 5xx) Retry only `429` and `5xx`. Treat `400`, `403`, `404`, and `422` as terminal — they will fail again unchanged. - Use exponential backoff with jitter, and cap the number of attempts. - On `429`, slow down overall. For market data, stream via DXLink instead of polling. - Repeated failed logins can get your IP blocked outright (~8 hours); requests then time out. If blocked, contact `api.support@tastytrade.com`. If `5xx` responses persist, check [status.tastytrade.com](https://status.tastytrade.com) for tastytrade's trading-system and quote status. That page does not report API or sandbox availability separately. Full retry/backoff guidance lives in [`/docs/guides/rate-limits-and-backoff`](/docs/guides/rate-limits-and-backoff). ## Money-moving requests (orders) Never blindly retry a submitted order — a naive retry can place a duplicate. Instead: 1. Run the order as a **dry-run first** to surface rejections (a rejection returns `422` with the reason in `error.message`). Each preflight failure in `error.errors[]` has its own `code`; a partial list of the codes and messages is under [Preflight errors and warnings](/reference/errors#preflight-errors). Preflight warnings are not in that `422`; they arrive in `data.warnings[]` of a successful response, whether a dry-run or a placed order. 2. Tag every order with a unique `external-identifier` in the request body. On an uncertain outcome (timeout or 5xx), query `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for that identifier **before** resubmitting — the API does **not** deduplicate retried submissions for you, and there is no generic idempotency-key header. (`ext-client-order-id` is a system-populated, read-only field on order responses and account-streamer messages; do not send it.) See [`/docs/guides/idempotency-and-retries`](/docs/guides/idempotency-and-retries). ## See also - [`/reference/errors`](/reference/errors) — the complete error code catalog - [`/reference`](/reference) — endpoint schemas to validate against - [`/docs/guides/rate-limits-and-backoff`](/docs/guides/rate-limits-and-backoff) - [`/docs/sdks-and-tools/mcp-server`](/docs/sdks-and-tools/mcp-server) ## Related - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) --- # Stream market data This guide walks you through streaming live quotes from tastytrade's quote provider (dxFeed) over the **DXLink** WebSocket. You mint a short-lived token from the REST API, open the socket, run the handshake, subscribe to symbols, and read the feed. For background on how the two tastytrade streamers differ and the full event catalog, see the concept page at `/docs/concepts/streaming`. This guide is the step-by-step task. ## 1. Get an API quote token Call `GET /api-quote-tokens` with your OAuth access token. Access tokens last 15 minutes — mint a fresh one with `POST /oauth/token` if needed — and remember the required `User-Agent: product/version` header on every REST call. See `/docs/get-started` for the auth flow. ```bash curl https://api.tastyworks.com/api-quote-tokens \ -H "Authorization: Bearer " \ -H "User-Agent: my-app/1.0.0" ``` The response gives you the token and the `dxlink-url` to connect to: ```json { "data": { "token": "", "dxlink-url": "wss://dxlink.example.com/realtime", "level": "api" }, "context": "/api-quote-tokens" } ``` **API quote tokens expire after 24 hours** — refresh before they lapse. You must be a fully onboarded tastytrade customer; a username/password-only registration is rejected with `quote_streamer.customer_not_found_error`. (Sandbox uses `https://api.cert.tastyworks.com`; production uses `https://api.tastyworks.com`.) In the sandbox, an account with a customer record got `"level": "demo"` and a `dxlink-url` ending in `/delayed`; the quote age was not measured, and a user without a customer record was not tested. ## 2. Open the DXLink WebSocket Open a WebSocket connection to the `dxlink-url` returned above. Message order matters — send the frames below in sequence. ## 3. SETUP This is the first frame. It negotiates the protocol version and keepalive timeout on channel `0`. ```json { "type": "SETUP", "channel": 0, "version": "0.1-DXF-JS/0.3.0", "keepaliveTimeout": 60, "acceptKeepaliveTimeout": 60 } ``` DXLink replies with its own `SETUP`, then sends an `AUTH_STATE` with `state: UNAUTHORIZED`. ## 4. AUTH When you see `AUTH_STATE` / `UNAUTHORIZED`, send your API quote token. DXLink replies with `AUTH_STATE` / `AUTHORIZED`. ```json { "type": "AUTH", "channel": 0, "token": "" } ``` ## 5. CHANNEL_REQUEST — open a channel A channel is a virtual sub-connection. Use separate channels to organize subscriptions (for example, equities on one channel, futures on another). Pick any number to identify it. ```json { "type": "CHANNEL_REQUEST", "channel": 3, "service": "FEED", "parameters": { "contract": "AUTO" } } ``` DXLink replies with `CHANNEL_OPENED` for that channel. ## 6. FEED_SETUP — configure fields Tell DXLink which fields you want for each event type, and request `COMPACT` data so events arrive as positional arrays rather than verbose objects. ```json { "type": "FEED_SETUP", "channel": 3, "acceptAggregationPeriod": 0.1, "acceptDataFormat": "COMPACT", "acceptEventFields": { "Quote": ["eventType", "eventSymbol", "bidPrice", "askPrice", "bidSize", "askSize"], "Trade": ["eventType", "eventSymbol", "price", "dayVolume", "size"], "Greeks": ["eventType", "eventSymbol", "volatility", "delta", "gamma", "theta", "rho", "vega"], "Summary": ["eventType", "eventSymbol", "openInterest", "dayOpenPrice", "dayHighPrice", "dayLowPrice", "prevDayClosePrice"] } } ``` DXLink replies with `FEED_CONFIG` confirming the format and aggregation period. ## 7. FEED_SUBSCRIPTION — subscribe to symbols Subscribe to one or more event types for one or more symbols in a single frame. DXLink keeps streaming these until you unsubscribe. The event types are listed under [Available events](#available-events) below. ```json { "type": "FEED_SUBSCRIPTION", "channel": 3, "reset": true, "add": [ { "type": "Quote", "symbol": "SPY" }, { "type": "Trade", "symbol": "SPY" }, { "type": "Summary", "symbol": "SPY" } ] } ``` Subscribe with DXLink-formatted symbols. tastytrade provides these in the `streamer-symbol` field on instrument responses (for example, futures `/6AM3` exposes `streamer-symbol: "/6AM23:XCME"`). Prefer that field over hand-building symbols. To stop a symbol, send another `FEED_SUBSCRIPTION` with a `remove` array of the same event/symbol pairs. ### Available events These are event types defined by dxFeed's DXLink protocol; use the exact name as the `type` value. This is not a guarantee that every type is served to you: which types a given feed returns depends on the feed and the token you connect with. The sandbox, for example, returned a delayed demo feed (see step 1). - **Quote** - **Trade** - **Summary** - **Greeks** - **TimeAndSale** (Time and Sale) - **Profile** - **Candle** To try the protocol interactively, dxFeed hosts a third-party [dxLink protocol and test page](https://demo.dxfeed.com/market-data/dxlink-ws/debug/#/protocol). It is not operated by tastytrade; paste the API quote token from step 1 when it asks for one. ## 8. Parse FEED_DATA In `COMPACT` form, `data` is a flat array: an event-type label followed by one positional row per event, with values in the order you requested in `FEED_SETUP`. ```json { "type": "FEED_DATA", "channel": 3, "data": [ "Trade", [ "Trade", "SPY", 559.36, 13743299, 100.0 ] ] } ``` DXLink publishes events only as they occur. A connected, heartbeating socket that receives nothing usually means the symbol has no current trading activity — that is normal, not a bug. ## 9. Keep the connection alive If DXLink does not receive a keepalive within its 60-second timeout, it closes the connection. Send a `KEEPALIVE` on channel `0` about every 30 seconds to hold it open indefinitely. ```json { "type": "KEEPALIVE", "channel": 0 } ``` ## Next steps - Reconnect with backoff on drops and respect the 60-second keepalive timeout — see `/docs/guides/rate-limits-and-backoff`. - For Candle (historical aggregate) events, symbology details, and the account streamer, see `/docs/concepts/streaming`. - Token-endpoint errors (`401`/`429`) are documented in `/reference/errors`; browse all endpoints in `/reference`. - For an agent integration that hands off to both streamers (quote-token tool + streaming protocol reference), see `/docs/sdks-and-tools/mcp-server`. ## Related - [Streaming](https://developer.tastytrade.com/docs/concepts/streaming.md) - [Market Data](https://developer.tastytrade.com/docs/concepts/market-data.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) --- # Stream account updates The account streamer is a one-directional WebSocket that pushes notifications whenever your account data changes — orders, balances, and positions, plus public watchlists and quote-alert triggers. Instead of polling REST endpoints to learn that an order went from `Routed` to `Filled`, you receive a push message as the status changes. This guide walks through opening the socket, subscribing, heartbeating, and handling inbound notifications. For background on how this relates to the DXLink market-data streamer, see `/docs/concepts/streaming`. ## Before you start You need a valid tastytrade OAuth access token. Every message you send over the socket includes an `auth-token` — the same value you send in the `Authorization` header for REST calls. Access tokens last 15 minutes, so include a currently valid `auth-token` in every message; when your token expires, obtain a new one, and reconnect if the server drops your session. See `/docs/get-started` for the full token flow, including the required `User-Agent: product/version` header on the REST call that mints the token. Pick the host that matches your environment: | Environment | WebSocket host | | --- | --- | | Sandbox | `wss://streamer.cert.tastyworks.com` | | Production | `wss://streamer.tastyworks.com` | These pair with the REST hosts `https://api.cert.tastyworks.com` (sandbox) and `https://api.tastyworks.com` (production). ## 1. Open the WebSocket connection Open a connection to the host above using your WebSocket client of choice, then wait for the open event before sending anything. ```js const WebSocket = require('ws') const host = 'wss://streamer.cert.tastyworks.com' const websocket = new WebSocket(host) websocket.addEventListener('open', () => { // Send the connect message, then schedule heartbeats }) websocket.addEventListener('message', (messageEvent) => { // Parse and handle inbound notifications }) ``` Order matters. If you heartbeat before you connect, you may get a `not implemented` error — only start heartbeats **after** a successful `connect`. ## 2. Send the connect message A `connect` message subscribes you to account updates for whichever account numbers you provide. Each message carries an `action`, a `value`, and your `auth-token`. The `request-id` is optional and is echoed back in the response so you can correlate messages. ```json { "action": "connect", "value": [ "5WT00000", "5WT00001" ], "auth-token": "", "request-id": 2 } ``` The server replies with a session id: ```json { "status": "ok", "action": "connect", "web-socket-session-id": "5b6e2799", "value": [ "5WT00000", "5WT00001" ], "request-id": 2 } ``` Other available actions are `heartbeat`, `public-watchlists-subscribe`, and `quote-alerts-subscribe`. Quote alerts are scoped to the user, not an individual account, and their `value` is left blank. ## 3. Send periodic heartbeats Once connected, send a `heartbeat` on a 2s–1m interval. This keeps the socket open and lets you detect connection drops. The `value` is blank for heartbeats. ```json { "action": "heartbeat", "auth-token": "", "request-id": 1 } ``` The server acknowledges each one: ```json { "status": "ok", "action": "heartbeat", "web-socket-session-id": "5b6e2799", "request-id": 1 } ``` If you stop heartbeating, the server may drop the connection. Reconnect with backoff on any drop — see `/docs/guides/rate-limits-and-backoff`. ## 4. Handle inbound notifications Notifications use the same JSON object representations as the REST API and always contain the **full** object — never a partial or differential update. Each message carries a `type` (the class of data), a `data` payload, and a `timestamp`. Note the dasherized JSON keys (`account-number`, `ext-client-order-id`), consistent with the rest of the API. For example, an order status change arrives as a `type: Order` notification: ```json { "type": "Order", "data": { "id": "1", "account-number": "5WT00000", "time-in-force": "Day", "order-type": "Market", "size": "100", "underlying-symbol": "AAPL", "underlying-instrument-type": "Equity", "status": "Live", "cancellable": true, "editable": true, "edited": false, "legs": [ { "instrument-type": "Equity", "symbol": "AAPL", "quantity": "100", "remaining-quantity": "100", "action": "Buy to Open", "fills": [] } ] }, "timestamp": 1688595114405 } ``` As the order advances (for example to `Filled`), you receive a new notification with the full updated object — no re-fetch required. ## Notes - The account streamer reports order state; it does not place orders. Submit orders over REST and watch the streamer for `Order` notifications as the status advances. - Include a currently valid `auth-token` in every message you send. If your token expires, obtain a new one — and reconnect if the server drops the session. - For token-endpoint error codes (`400`/`401`/`403`/`404`/`422`/`429`/`5xx`), see `/reference/errors`. REST object schemas (such as the `Order` payload) live in `/reference` under the orders group; the websocket message schemas (connect/heartbeat requests, acks, and the notification envelope) are defined in the streaming AsyncAPI spec — [JSON](/asyncapi/tastytrade-streaming.asyncapi.json) or [YAML](/asyncapi/tastytrade-streaming.asyncapi.yaml). ## Related - [Streaming](https://developer.tastytrade.com/docs/concepts/streaming.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) --- # Run a backtest This how-to walks you through the tastytrade options backtester: submit a backtest definition, poll the backtest by id until it finishes, then read the resulting statistics, trials, and snapshots. This guide assumes you already have an access token. If not, see [Get started](/docs/get-started). The backtester is its own service on its own host: all examples use `https://backtester.vast.tastyworks.com` — the server published in its OpenAPI spec — not the main `api.tastyworks.com` gateway, and there is no separate cert/sandbox instance. Authentication works the same way as the rest of the API: send your token in the `Authorization` header (the backtester validates it against tastytrade's auth service). Unlike the core API, responses are plain JSON objects with camelCase keys (for example `startDate`) — there is no `data`/`context` envelope. For the complete operation, parameter, and schema reference, see [/reference/backtesting](/reference/backtesting). ## Before you start - A 15-minute OAuth access token from `POST /oauth/token`. - A `User-Agent: product/version` header — required across the tastytrade API, so send it here too. - A backtest definition: an underlying `symbol`, a `startDate`/`endDate` range, and one or more `legs`. To confirm a symbol has history for your date range, call `GET /available-dates`, which returns each available symbol with its `startDate` and `endDate`. ## 1. Build the backtest request A backtest defines a strategy over a historical window. Each entry in `legs` describes one position. The required leg fields are `type`, `direction`, `quantity`, `strikeSelection`, and `daysUntilExpiration`. For an `equity-option` leg also set `side` (`call` or `put`). `strikeSelection` decides which strike is chosen, and the value you supply depends on it. For example, with `"strikeSelection": "delta"` you provide a numeric `delta` (the 16-delta short put in the example below). Other modes include `percentageOTM`, `currentPriceOffset`, and `premium`. Optional `entryConditions` and `exitConditions` control when trials open and close. Here is a short-put strategy on SPY, selling the 16-delta put 45 days out, entered every day, with a 50% take-profit: ```json { "symbol": "SPY", "startDate": "2022-01-01", "endDate": "2022-12-31", "legs": [ { "type": "equity-option", "direction": "short", "side": "put", "quantity": 1, "strikeSelection": "delta", "delta": 16, "daysUntilExpiration": 45 } ], "entryConditions": { "frequency": "every day" }, "exitConditions": { "takeProfitPercentage": 50 } } ``` ## 2. Submit the backtest `POST` the definition to `/backtests`. ```bash curl -X POST "https://backtester.vast.tastyworks.com/backtests" \ -H "Authorization: Bearer " \ -H "User-Agent: my-app/1.0.0" \ -H "Content-Type: application/json" \ -d @backtest.json ``` The response is a backtest object. A `201` means the backtest is **pending** and still running; a `200` means it is already ready. Either way the body includes an `id` you use to poll. A malformed body returns `400`; see [/reference/errors](/reference/errors). ## 3. Poll for completion Fetch the backtest by id and watch its `status`, which moves through `pending`, `running`, and `completed`: ```bash curl "https://backtester.vast.tastyworks.com/backtests/{id}" \ -H "Authorization: Bearer " \ -H "User-Agent: my-app/1.0.0" ``` While it runs, the object reports `progress` and an `ETA` you can use to space out polls. An unknown id returns `404`. Poll on an interval rather than tightly looping, and on `429` back off per [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). ## 4. Read the results Once `status` is `completed`, read these fields from the backtest object: | Field | What it contains | |-------|------------------| | `statistics` | Aggregate performance metrics for the run. | | `trials` | Each simulated trade, with `openDateTime`, `closeDateTime`, and `profitLoss`. | | `snapshots` | Time series of `profitLoss` and `underlyingPrice` at each `dateTime`. | | `notices` | Conditional annotations (for example, overlapping ranges due to a stock split). | For step-by-step execution detail, fetch `GET /backtests/{id}/logs`. To stop a long run early, `POST /backtests/{id}/cancel` (returns `204`). To list your existing backtests, `GET /backtests` returns an array of ids. ## Try a single trade first To check historical pricing for one trade without defining a full backtest, `POST /simulate-trade` with an `underlying` and `legs` (each leg uses tastytrade/OCC symbology). It returns a series of `dateTime`, `price`, `effect` (`debit`/`credit`), `underlyingPrice`, and `delta` points. ## Next steps - Browse every operation and schema at [/reference/backtesting](/reference/backtesting). - Explore all endpoints in the [API reference](/reference). - Handle failures with [Idempotency & retries](/docs/guides/idempotency-and-retries) and [Rate limits & backoff](/docs/guides/rate-limits-and-backoff). ## Related - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [Instruments & Symbology](https://developer.tastytrade.com/docs/concepts/instruments-and-symbology.md) - [Market Data](https://developer.tastytrade.com/docs/concepts/market-data.md) --- # Manage watchlists A watchlist is a named collection of instruments you want to track. This guide walks through managing your own (user) watchlists: listing them, creating one, fetching it by name, replacing it, and deleting it. tastytrade also publishes read-only **public** watchlists and **pairs** watchlists that any client can fetch. All requests go to the sandbox base URL `https://api.cert.tastyworks.com` or production `https://api.tastyworks.com`. Every request must send a valid OAuth access token (`Authorization: Bearer `, minted via `POST /oauth/token`, 15-minute expiry) and a `User-Agent: product/version` header (see [Get started](/docs/get-started)). JSON keys are dasherized (for example `watchlist-entries`, `instrument-type`, `order-index`). ## 1. List your watchlists `GET /watchlists` returns every watchlist for the authenticated user. ```bash curl https://api.cert.tastyworks.com/watchlists \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" ``` ## 2. Create a watchlist `POST /watchlists` creates a watchlist. The request body requires `name` and `watchlist-entries`. Each entry requires a `symbol`; `instrument-type` is optional but recommended so the symbol resolves unambiguously. See [Instruments and symbology](/docs/concepts/instruments-and-symbology) for valid symbol formats and instrument types. You may also set an optional `group-name` and `order-index` (defaults to `9999`). ```json { "name": "Tech Megacaps", "group-name": "Sectors", "order-index": 10, "watchlist-entries": [ { "symbol": "AAPL", "instrument-type": "Equity" }, { "symbol": "MSFT", "instrument-type": "Equity" } ] } ``` ```bash curl -X POST https://api.cert.tastyworks.com/watchlists \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" \ -H "Content-Type: application/json" \ -d '{ "name": "Tech Megacaps", "watchlist-entries": [ { "symbol": "AAPL", "instrument-type": "Equity" }, { "symbol": "MSFT", "instrument-type": "Equity" } ] }' ``` A successful create returns `201 Created` with the stored watchlist. Creating is **not** idempotent, so retrying after a network error may produce a duplicate — confirm with a list call before retrying. See [Idempotency and retries](/docs/guides/idempotency-and-retries). ## 3. Get a watchlist by name `GET /watchlists/{watchlist_name}` returns a single watchlist. URL-encode the name if it contains spaces (for example `Tech%20Megacaps`). ```bash curl "https://api.cert.tastyworks.com/watchlists/Tech%20Megacaps" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" ``` ## 4. Update (replace) a watchlist `PUT /watchlists/{watchlist_name}` replaces **all** properties of the watchlist. This is a full replacement, not a merge: send the complete `watchlist-entries` array you want to keep — entries omitted from the body are removed. The body uses the same shape as create and requires `name` and `watchlist-entries`. ```bash curl -X PUT "https://api.cert.tastyworks.com/watchlists/Tech%20Megacaps" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" \ -H "Content-Type: application/json" \ -d '{ "name": "Tech Megacaps", "watchlist-entries": [ { "symbol": "AAPL", "instrument-type": "Equity" }, { "symbol": "MSFT", "instrument-type": "Equity" }, { "symbol": "NVDA", "instrument-type": "Equity" } ] }' ``` To rename a watchlist, set a new `name` in the body. `PUT` returns `200 OK` with the updated watchlist. ## 5. Delete a watchlist `DELETE /watchlists/{watchlist_name}` removes the watchlist and returns `200 OK` with the deleted watchlist. ```bash curl -X DELETE "https://api.cert.tastyworks.com/watchlists/Tech%20Megacaps" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-app/1.0.0" ``` ## Public and pairs watchlists (read-only) These endpoints are shared by tastytrade and cannot be modified: | Operation | Endpoint | | --- | --- | | List public watchlists | `GET /public-watchlists` | | Get one public watchlist | `GET /public-watchlists/{watchlist_name}` | | List pairs watchlists | `GET /pairs-watchlists` | | Get one pairs watchlist | `GET /pairs-watchlists/{pairs_watchlist_name}` | `GET /public-watchlists` accepts an optional `counts-only` query parameter (boolean, default `false`) to return entry counts instead of full entries. ## Error handling Watchlist endpoints use standard HTTP status codes — `422` for malformed or invalid bodies, `401`/`403` for auth problems, `404` for an unknown watchlist name, and `429` when you are rate limited (see [Rate limits and backoff](/docs/guides/rate-limits-and-backoff)). See [Error reference](/reference/errors) for the response shape. ## Reference - [Watchlists API reference](/reference/watchlists) - [Instruments and symbology](/docs/concepts/instruments-and-symbology) - [Full API reference](/reference) ## Related - [Instruments & Symbology](https://developer.tastytrade.com/docs/concepts/instruments-and-symbology.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) --- # Pagination & filtering List endpoints that can return many records — such as transactions and orders — accept query parameters to page through results, filter them down, and sort them. This guide walks through doing all three against a real endpoint. Before you start, make sure you can authenticate. Every request needs a valid `Authorization: Bearer ` header (15-minute OAuth access tokens from `POST /oauth/token`) and a `User-Agent: product/version` header. See [Get started](/docs/get-started) for the basics. ## 1. Know the pagination parameters tastytrade list endpoints use **offset-based** pagination with two query parameters: | Parameter | Type | Default | Meaning | | --- | --- | --- | --- | | `page-offset` | integer | `0` | Which page to fetch. `0` is the first page. | | `per-page` | integer | varies | How many items per page (e.g. `250` for transactions, `10` for orders). | Both keys are dasherized, like all tastytrade query keys. Responses follow the standard envelope: a `data` object containing an `items` array, plus a `context` field echoing the request path. Paginated list responses also include a top-level `pagination` block describing the current page (`per-page`, `page-offset`, `item-offset`, `total-items`, `total-pages`, `current-item-count`). ## 2. Request the first page Use `GET /accounts/{account_number}/transactions` as the example. Substitute your real `account_number`, and use the sandbox host `https://api.cert.tastyworks.com` while testing (production is `https://api.tastyworks.com`). ```bash curl "https://api.cert.tastyworks.com/accounts/{account_number}/transactions?page-offset=0&per-page=250" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-custom-client/1.0" \ -H "Accept: application/json" ``` A successful response looks like: ```json { "data": { "items": [ { "id": 123, "transaction-type": "Trade" } ] }, "context": "/accounts/{account_number}/transactions", "pagination": { "per-page": 250, "page-offset": 0, "item-offset": 0, "total-items": 1622, "total-pages": 7, "current-item-count": 250 } } ``` ## 3. Iterate until the collection is exhausted Walk forward one page at a time, incrementing `page-offset` by 1 on each request while keeping `per-page` constant: 1. Request `page-offset=0`. 2. Process every entry in `data.items`. 3. Use the `pagination` block to decide when to stop: you are on the last page when `page-offset + 1 >= pagination.total-pages` (equivalently, when `current-item-count` is less than `per-page`). As a fallback, if a response has no `pagination` block, stop when `items` comes back with fewer than `per-page` entries (or empty). 4. Otherwise increment `page-offset` and repeat. ```bash # page 2 (the second page of 250) curl "https://api.cert.tastyworks.com/accounts/{account_number}/transactions?page-offset=1&per-page=250" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-custom-client/1.0" ``` Keep `per-page` modest and page steadily rather than hammering the endpoint — a burst of rapid requests can earn an HTTP 429. See [Rate limits and backoff](/docs/guides/rate-limits-and-backoff). ## 4. Sort the results The `sort` parameter controls ordering. It accepts `Desc` or `Asc` and defaults to `Desc` (newest first): ```bash curl "https://api.cert.tastyworks.com/accounts/{account_number}/transactions?sort=Asc&per-page=250" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-custom-client/1.0" ``` ## 5. Narrow results with filters Filtering server-side returns fewer pages and less data to walk. The transactions endpoint supports filters such as: | Parameter | Description | | --- | --- | | `start-date` / `end-date` | Bound the query to a date range. `end-date` defaults to now. | | `start-at` / `end-at` | Same bounds, but full date-time precision. | | `symbol` | A single instrument symbol, e.g. `AAPL`. | | `underlying-symbol` | The underlying ticker or future symbol. | | `instrument-type` | e.g. `Equity`, `Equity Option`, `Future`, `Cryptocurrency`. | | `action` | e.g. `Buy to Open`, `Sell to Close`. | | `type` | A single transaction type. | Some filters accept multiple values as an array. Per tastytrade conventions, repeat the key with `[]`, e.g. `types[]=Trade&types[]=Money%20Movement` (URL-encode values that contain spaces). Note that `type` and `types[]` are mutually exclusive — supply one or the other, not both: ```bash curl "https://api.cert.tastyworks.com/accounts/{account_number}/transactions?start-date=2024-01-01&end-date=2024-01-31&instrument-type=Equity&types[]=Trade&per-page=250" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "User-Agent: my-custom-client/1.0" ``` Filters, sorting, and pagination combine freely in a single request. Orders behave the same way — `GET /accounts/{account_number}/orders` accepts the same `page-offset`, `per-page`, and `sort` parameters plus its own filters like `status` and `underlying-symbol`. The date bounds on order searches are not optional in every version. In order-api version `20261012`, `GET /accounts/{account_number}/orders` and `GET /customers/{customer_id}/orders` require at least one of `start-date` or `start-at`, and a request with neither returns HTTP 400. In version `20250813` neither is required. The date range is applied to each order's last-updated time. `start-date` is read as a date in US Eastern time, so it matches from the start of that day in US Eastern time, up to the end of `end-date` (today if omitted). If you send both `start-date` and `start-at`, `start-date` is used. A client in another time zone should send a `start-date` on or before the day it submitted the order (for example, the previous day), or send `start-at` with an explicit UTC offset instead. ## Errors A malformed page or filter value returns HTTP 400; an invalid or expired token returns 401. See [Errors](/reference/errors) for the full list. ## Reference - [API reference](/reference) — every list endpoint and its parameters. - [Transactions](/reference/transactions) — the transactions endpoint used above. - [Orders](/reference/orders) — paginated and filterable order lists. The exact parameter set varies by endpoint. When in doubt, confirm the supported pagination, sort, and filter parameters for a specific endpoint in the [reference](/reference) rather than assuming. ## Related - [Rate limits & backoff](https://developer.tastytrade.com/docs/guides/rate-limits-and-backoff.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) - [Positions & Balances](https://developer.tastytrade.com/docs/concepts/positions-and-balances.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) --- # MCP Server The tastytrade **MCP server** gives AI agents structured access to the tastytrade API through the [Model Context Protocol](https://modelcontextprotocol.io/). It exposes the API as MCP **Tools**, **Resources**, and **Prompts**, and gates order submission behind a dry-run-first confirmation flow. > **Self-hosted and open source.** You run it yourself. The source is at > [github.com/tastytrade/tastytrade-mcp](https://github.com/tastytrade/tastytrade-mcp). > There is no tastytrade-hosted endpoint to connect to. > **The default endpoint is production.** With no environment configured, the > server connects to the production API, where every account the supplied > credentials can reach is a **real brokerage account** and every order moves > **real money**, immediately and irreversibly. Set `TASTYTRADE_ENV=sandbox` for > an environment with no real money in it, and `TASTYTRADE_READ_ONLY=1` to > withhold every write and destructive tool. > > Production is the default deliberately: the sandbox does not serve the REST > market-data routes (`/market-data` and `/market-metrics` return HTTP 502), and a > default endpoint that cannot quote would teach operators to override it without > reading why. ## Why an MCP server (vs. calling the REST API directly) Trading APIs are unforgiving — wrong quantity, wrong account, or wrong symbol costs real money. The MCP server adds guardrails enforced server-side, so an agent cannot skip them: - **Tools** — direct API actions (get a quote, place an order, cancel an order…). - **Resources** — documentation bundles and computed account views the agent reads instead of stitching several tool calls together. - **Prompts** — pre-composed tool-call plans (LLMs follow plans more reliably than they compose them). ## Install Clone-and-build is the supported install. Nothing is published to npm, and there is no published container image. ```bash git clone https://github.com/tastytrade/tastytrade-mcp.git cd tastytrade-mcp npm ci npm run build ``` Requires **Node.js 22 or newer**. The repo includes a `Dockerfile` that builds an image locally — note that a stdio server must be started with `docker run -i`, or the container exits immediately and looks like a crash. ## Credentials Authentication is **environment-only**; there is no interactive login flow. Create an OAuth client and refresh token out of band (see the [OAuth2 guide](/docs/authentication/oauth2), or my.tastytrade.com → Manage → My Profile → API), then supply three variables: | Variable | Required | | -------------------------- | -------- | | `TASTYTRADE_CLIENT_ID` | yes | | `TASTYTRADE_CLIENT_SECRET` | yes | | `TASTYTRADE_REFRESH_TOKEN` | yes | **Sandbox credentials are a separate OAuth application and are not interchangeable with production ones.** A sandbox refresh token cannot mint an access token against production, or vice versa — and the failure is uninformative: every tool call returns `auth_failed` with nothing saying why. The server does not auto-load a `.env` file. Export the variables yourself, or pass them through your MCP client's `env` block. ## Choosing an environment | Variable | Effect | | ------------------------ | ------------------------------------------------------------- | | `TASTYTRADE_ENV` | `production` (default) or `sandbox`. Unset means production. | | `TASTYTRADE_API_URL` | Explicit base URL; wins over `TASTYTRADE_ENV`. | | `TASTYTRADE_READ_ONLY` | `1` withholds and refuses all 14 write and destructive tools. | | `MAX_ORDER_NOTIONAL_USD` | Ceiling on an order's buying-power impact (default `50000`). | A `TASTYTRADE_ENV` the server cannot read — a typo like `sandbx` — resolves to the **sandbox** and says so, on the principle that a failed instruction must not land in the same place as an unset default. `TASTYTRADE_READ_ONLY` fails closed the same way. Three surfaces announce the active environment: a **stderr startup banner**, the **`instructions`** field of the MCP initialize result (the only signal the agent itself can read), and an **`environment` member on every order and dry-run result**, so a transcript is evidence of where an order actually went. ### What the sandbox cannot do The sandbox does not serve REST market data — `/market-data` and `/market-metrics` return HTTP 502 — so quote snapshots, market metrics, historical dividends and earnings reports all fail there. For an account with a customer record, `/api-quote-tokens` returned a `demo`-level token with a `/delayed` URL (see [Sandbox](/docs/sandbox)). Everything else works: instruments, option chains, futures, accounts, balances, positions, transactions, orders, and the dry-run and submission paths. The sandbox also resets every 24 hours, clearing trades, transactions and positions. ## Connecting a client The server speaks MCP over **stdio**: the client launches it as a subprocess. What is constant across clients is the command (`node`), the absolute path to `dist/index.js`, and the environment variables. **Claude Desktop** (`claude_desktop_config.json`): ```json { "mcpServers": { "tastytrade": { "command": "node", "args": ["/absolute/path/to/tastytrade-mcp/dist/index.js"], "env": { "TASTYTRADE_ENV": "sandbox", "TASTYTRADE_CLIENT_ID": "…", "TASTYTRADE_CLIENT_SECRET": "…", "TASTYTRADE_REFRESH_TOKEN": "…" } } } } ``` Every value in that object is a string, `"1"` included. Name the environment explicitly rather than relying on the default, so the block cannot mean something different from what it says. **Claude Code** writes the file for you: ```bash claude mcp add tastytrade \ -e TASTYTRADE_CLIENT_ID=… \ -e TASTYTRADE_CLIENT_SECRET=… \ -e TASTYTRADE_REFRESH_TOKEN=… \ -- node /absolute/path/to/tastytrade-mcp/dist/index.js ``` `-s project` writes a shareable `.mcp.json` instead — which makes it the wrong place for a client secret or refresh token. Other clients (Cursor, Zed, Continue among them) keep their own config file and do not all use the same key; check your client's documentation. ## Tool surface **84 tools** — 70 read-only, 2 write, 12 destructive. Read-only tools are auto-approvable; every tool carries MCP annotations (`readOnlyHint` / `destructiveHint` / `idempotentHint`) so clients render the right approval UI. **Five tools require a confirmation token** — the five that submit or change an order: `tastytrade_place_order`, `tastytrade_edit_order`, `tastytrade_replace_order`, `tastytrade_place_complex_order` and `tastytrade_edit_complex_order`. Each takes a single-use `confirmation_token` minted by its own `dry_run_*` tool, valid for **60 seconds** and bound to a hash of the submitted arguments _and_ of the request target — so you cannot dry-run one share and submit a thousand, or pre-flight against one endpoint and submit to another. **The other seven destructive tools carry no token and have no dry-run.** They are `tastytrade_cancel_order`, `tastytrade_cancel_complex_order`, `tastytrade_delete_quote_alert`, and the four watchlist mutators (`tastytrade_update_watchlist`, `tastytrade_delete_watchlist`, `tastytrade_add_watchlist_symbol`, `tastytrade_remove_watchlist_symbol`). Of those seven only the two cancels touch orders; the other five move no money. They act on the first call, and each says so in its own description. ## Safety model In order of how much they protect you: 1. **Dry-run-first confirmation** — the five order-submitting tools will not act without a token from their own dry-run (above). It covers those five and none of the other destructive tools. 2. **Pre-submit sanity checks** — per-leg quantities against the account's own published order-size ceilings, a notional cap on buying-power impact (`MAX_ORDER_NOTIONAL_USD`, default $50,000), and a refusal to send orders into frozen or closing-only accounts. Every result names the checks that did **not** run, so an empty warning list can never be mistaken for a completed check. 3. **Credential-destination guard** — the refresh token and client secret are only sent to a recognised tastytrade host over an encrypting channel. An unrecognised host stops the server rather than warning about it. 4. **Rate limiting** — tastytrade's own published per-second, per-endpoint ceilings plus a 50/sec global cap, charged once per call. See [Rate limits and backoff](/docs/guides/rate-limits-and-backoff). 5. **Bounded, attributed output** — everything the broker wrote is nested under an `upstream` member and marked as untrusted external content, bounded in size and stripped of display-hostile codepoints, so it cannot impersonate the server's own fields. ## Verify it starts Two JSON-RPC lines on stdin prove the server starts and lists its tools. Neither call reaches tastytrade, so this works before the credentials are right: ```bash printf '%s\n' \ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}' \ '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \ | node dist/index.js | cut -c1-200 ``` Startup diagnostics go to **stderr**, because stdout carries the MCP protocol and nothing else. A client writes stderr to its own server log — that log is where to look when a client reports the server failed to start. ## See also - [github.com/tastytrade/tastytrade-mcp](https://github.com/tastytrade/tastytrade-mcp) — source, full README, and security policy. - [API Reference](/reference) — the underlying REST operations these tools wrap. - [`/llms.txt`](/llms.txt) — the agent index, including the golden-path instructions. ## Disclosures The tastytrade Model Context Protocol (“MCP”) Server lets you connect a third-party AI application or Large Language Model (“LLM”) (collectively, an “AI System”) of your choosing to your tastytrade account(s) to research markets, analyze your portfolio, and place orders in plain language. How you use your AI System is up to you — from an interactive assistant where you review and confirm each order, to an automated system you build and operate yourself. You are responsible for how the server is configured and used, including any automated or unattended trading conducted by or through your chosen AI System, and for all orders placed from your account. tastytrade does not endorse or recommend any third-party AI System, and tastytrade is not responsible for any information, output, or trading activity generated by or through your connected AI System. Any AI-generated information should be independently verified. You are solely responsible for any actions taken in reliance on information generated by your AI System and for any investment or trading decisions made using it. You are responsible for monitoring any activity undertaken by or through your AI System to ensure it is operating as you intended. Once you share your account data with an AI System provider you select, it leaves tastytrade's environment and is governed by that provider's terms and privacy practices. tastytrade is not responsible for any unauthorized access to your account data resulting from your usage of an AI System. AI Systems can make errors. They may misinterpret instructions, act on incomplete or outdated information, or produce analysis that is inaccurate or unsuitable for you. You are solely responsible for reviewing all your AI-generated output, orders, and account activity. tastytrade does not guarantee the accuracy, completeness, or suitability of any of your AI-generated output. Trading securities, options, and futures involves significant risk and is not suitable for all investors; you may lose more than your initial investment. Before trading options, read the [Characteristics and Risks of Standardized Options](https://assets.tastyworks.com/production/documents/USA/characteristics_and_risks_of_standardized_options.pdf) and [Futures & Exchange-Traded Options Risk Disclosure Statement](https://assets.tastyworks.com/production/documents/USA/futures_exchange_traded_options_risk_disclosure_agreement.pdf). We recommend testing with paper trading before connecting a live account. tastytrade, Inc. is a registered broker-dealer and a member of FINRA, NFA, and SIPC. **Disclosures:** [tastytrade MCP Server — Disclosures (PDF)](/disclosures/tastytrade-mcp-server-disclosures.pdf) ## Related - [Agent Quickstart](https://developer.tastytrade.com/docs/agent-quickstart.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Streaming](https://developer.tastytrade.com/docs/concepts/streaming.md) --- # FAQ Answers to the questions we hear most often. For the full catalog of error codes and their meanings, see [/reference/errors](/reference/errors). New to the API? Start at [/docs/get-started](/docs/get-started). ## Why am I suddenly getting `unconfirmed_user` errors? All users must confirm their email address within 3 days of signing up. This includes sandbox users. To confirm your email address, request a confirmation email: ```bash curl -X POST https://api.cert.tastyworks.com/confirmation \ -H "Content-Type: application/json" \ -d '{ "email": "you@example.com" }' ``` Check your inbox for a link to confirm your email address. Once you have clicked the link and see a success message, you are good to go. ## Why do I keep getting `invalid_credentials` errors? This error occurs when your username or password is wrong during login. Be sure you are hitting the correct environment. There is a sandbox environment and a production environment, and each requires a **separate** set of credentials. If you hit production with your sandbox credentials (or vice versa), you will likely see `invalid_credentials`. To diagnose which environment you are hitting, check the URL of your request: | Environment | Base URL | | --- | --- | | Sandbox | `https://api.cert.tastyworks.com` | | Production | `https://api.tastyworks.com` | If needed, you can reset your production password at [tastytrade.com](https://tastytrade.com/). ## Why am I getting a 401 when my credentials are valid? tastytrade has specific requirements around the `User-Agent` header. The format must be `/` (for example, `my-app/1.0.0`). Without a valid `User-Agent`, you will get a 401 with an HTML response like this: ```html 401 Authorization Required

401 Authorization Required


nginx
``` This nginx-style 401 (rather than a JSON error body) is the tell-tale sign that the `User-Agent` header is missing or malformed. ## Why am I getting `unauthorized` errors? This error occurs when you do not have a valid access token. OAuth access tokens last 15 minutes and must be sent in the `Authorization` header on **every** request. Generate a fresh token with `POST /oauth/token` and include it on each subsequent request: ```http GET /customers/me/accounts HTTP/1.1 Host: api.cert.tastyworks.com User-Agent: my-app/1.0.0 Authorization: Bearer ``` When a token expires, you will start seeing 401s again — refresh it rather than reusing a stale one. ## Why are my HTTP requests suddenly timing out? tastytrade will block your IP address outright if we receive too many failed login attempts within a short period. We do this to protect users' accounts from being brute-forced. The IP block typically lasts about 8 hours. During that time you cannot connect to any endpoint — requests simply time out. To request an early unblock, email [api.support@tastytrade.com](mailto:api.support@tastytrade.com). ## How do I reset my sandbox user password? On the sandbox sign-in page, look for the "Reset it here" link under the sign-in button. Enter your email address and check your inbox for further instructions. ## Can I delete my sandbox user? No. If you no longer have access to the email account tied to it, contact [api.support@tastytrade.com](mailto:api.support@tastytrade.com). ## I can't access the sandbox environment (`ENOTFOUND` / `Failed to resolve`) If you see errors like `Failed to resolve` or `ENOTFOUND`, make sure you are using the correct host. The sandbox URL is `api.cert.tastyworks.com`. For example, to fetch your accounts you would hit: ```bash curl https://api.cert.tastyworks.com/customers/me/accounts \ -H "User-Agent: my-app/1.0.0" \ -H "Authorization: Bearer " ``` ## Do you have rate-limit or retry guidance? Yes — see [/docs/guides/rate-limits-and-backoff](/docs/guides/rate-limits-and-backoff) for handling 429s and 5xx responses with backoff. ## Is there a status page? [status.tastytrade.com](https://status.tastytrade.com) reports the status of tastytrade's trading systems and quotes. It does not report API or sandbox availability separately. For persistent `5xx` responses, see [/docs/guides/error-handling](/docs/guides/error-handling). ## How do I avoid placing a duplicate order? Always dry-run an order first, then submit the live order with a unique `external-identifier` in the request body. The API does not de-duplicate retried submissions, and there is no idempotency-key header — if the outcome of a submission is uncertain (timeout or 5xx), check `GET /accounts/{account_number}/orders` with a `start-date` on or before the day you submitted, in US Eastern time (for example, the previous day), or `/orders/live`, for your `external-identifier` **before** resubmitting. See [/docs/guides/idempotency-and-retries](/docs/guides/idempotency-and-retries) for the full pattern. ## Where can I find sample code or the full API reference? See the SDKs and tooling pages, including the [MCP server](/docs/sdks-and-tools/mcp-server), and browse the complete endpoint list at [/reference](/reference). ## Related - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) - [Idempotency & retries](https://developer.tastytrade.com/docs/guides/idempotency-and-retries.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) --- # Sandbox The sandbox is a full copy of the tastytrade API backed by simulated money. Use it to build and test order flow before pointing anything at a real account. Orders placed in the sandbox **never reach a real market**. They stay inside the sandbox system. ## Base URLs | | Production | Sandbox | | ---------------- | ------------------------------- | ------------------------------------ | | REST API | `https://api.tastyworks.com` | `https://api.cert.tastyworks.com` | | Account streamer | `wss://streamer.tastyworks.com` | `wss://streamer.cert.tastyworks.com` | Everything else about a request is identical: same paths, same payloads, same `Authorization` and `User-Agent` header rules. See [Auth patterns](/docs/authentication/oauth2). ## How fills are decided Sandbox orders are routed to a market simulator, not to a real venue. Of the fill behaviour described here, only two things were exercised in the sandbox, both by testing: the destination venue on equity fills, and the observations (the `AAPL` orders below, and the quote-token request under "What the sandbox cannot do"), each dated where it appears. Every rule in the list further down is read from source and was not run. - Equity fills in orders placed on 2026-08-28 and 2026-10-16 came back with a destination venue of `MARKET_SIMULATOR_A`. The sandbox is also configured with a second simulator router, `MARKET_SIMULATOR_CME`; which orders go to it has not been checked. - The old fixed table (market orders at $1, limit orders filling under or over $3) did not match those `AAPL` orders. Two market buys filled at prices in the hundreds of dollars, and two limit buys at $1.00 placed on 2026-08-28 while the equity market was open did not fill in the 24 and 56 seconds each was watched. The rules below are read from the source of `tastyworks/market-simulator` version 1.20.0, the version the sandbox deployment configuration pins. The version actually running was not confirmed, so check the rules against your own orders. The simulator's README says it does not replicate the venue-specific behaviour of each destination venue. For symbols outside the scripted list below, the simulator prices an order from the quote it receives for the instrument: - **Orders that fill.** The simulator takes the quote's **mid price** and rounds it to the tick: up for a buy, down for a sell. A limit order is compared with that rounded price, not the raw mid: a buy limit at or above it, or a sell limit at or below it, fills. A market order is priced to meet it. A filled order gets the rounded mid, not your limit price. With a spread of one tick, rounding puts a buy at the ask and a sell at the bid. - **When an order is checked.** At 1.20.0 an equity-based order is tried against the current quote when it arrives only inside market hours (or extended hours for an extended-hours order). An order with no equity-based leg, or one that arrives outside those hours, does not fill on arrival. - **Orders that do not fill on arrival.** An order with a time in force of immediate-or-cancel or fill-or-kill is cancelled. An order with any other time in force goes to the book, and the book is evaluated when a quote arrives for the instrument. If there is no quote, nothing fills. Day orders are expired at the close. - **Size.** The quoted size is the smaller of the bid size and the ask size (the smallest across the legs of a multi-leg order). An order larger than that fills in steps, each priced one tick worse than the last, and reports the average price. A limit order stops stepping at its limit. - **Multi-leg orders.** Each leg is priced from its own mid, and the net price is compared with the order's limit. The source has code for equity-based and futures-based instruments and for multi-leg orders. Only equity fills have been seen in the sandbox. Cryptocurrency orders have not been tested, so do not rely on them filling. A fixed set of tickers does not use the quote. They follow scripted outcomes (reject, rest, fill, partial fill, cancel) instead, and their fills are priced by a fixed rule: a limit order fills at its own limit price, and a market order fills at a constant price from the simulator's configuration. The configuration lists the equities `NAT` (reject), `TK` (rest forever), `SWBI` (immediate fill), `CCRN`, `GSL`, `CRON`, `TPVG`, `DC`, `FLGT`, `NEOG`, `WGO`, `PENG`, `MUX`, `BGS`, `IDR` and `ASTL`, and the futures `ZZZZZ1` to `ZZZZZ11`. If you place an order in one of these and the result looks unrelated to the market, this is why. This page makes no claim about how current the simulator's quotes are. Do not assume they match the live market. ## Credentials are separate **Sandbox credentials are a different OAuth application from production, and the two are not interchangeable.** A sandbox refresh token cannot mint an access token against production, and a production one cannot against the sandbox. The failure is uninformative when you get this wrong: every call returns `invalid_credentials` with nothing indicating the environment is the problem. If you are getting auth errors that make no sense, check which base URL your token was issued for first. ## What the sandbox cannot do - **REST market data is not served.** `/market-data` and `/market-metrics` return HTTP 502 on every route, so quote snapshots, market metrics, historical dividends and earnings reports all fail. Everything else works: instruments, option chains, futures, accounts, balances, positions, transactions, orders, and the dry-run and submission paths. - **Streaming quotes: one observation.** On 2026-10-28, for one sandbox account that had a customer record, `GET /api-quote-tokens` returned a `demo`-level token and a `dxlink-url` ending in `/delayed`, and that feed streamed `AAPL` quotes. How old those quotes were was not measured. A user without a customer record was not tested. See [Streaming market data](/docs/guides/stream-market-data). - **Net liquidating value history** is production-only. - **The environment resets every 24 hours**, clearing trades, transactions and positions while leaving users and accounts intact. Do not build a test that depends on state surviving overnight. Because the REST quote routes do not work in the sandbox, a common pattern is to read market data from production and submit orders to the sandbox, using two sets of credentials. ## Getting a sandbox account Use the [sandbox account tool](/docs/sandbox/tools) to create a sandbox user and sign in, in your browser. It talks to `api.cert.tastyworks.com` directly and cannot reach production. It also creates the customer record and funded account most endpoints need, manages OAuth applications and grants, and carries live account-streamer and market-data demos. ## Related - [OAuth2](/docs/authentication/oauth2) — creating an application, grants and access tokens. - [Quickstart](/docs/get-started) — first call, end to end. - [Place an equity order](/docs/guides/place-an-equity-order) — the order path to exercise here. - [Order lifecycle](/docs/concepts/order-lifecycle) — what the statuses mean. ## Related - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) - [Place an equity order](https://developer.tastytrade.com/docs/guides/place-an-equity-order.md) - [Order Lifecycle](https://developer.tastytrade.com/docs/concepts/order-lifecycle.md) --- # API Versions tastytrade sometimes needs to introduce breaking changes to an endpoint. Rather than change it under you, the existing version is deprecated and the breaking change goes into a **new API version**. ## Versions are dates A version is always the date it was introduced, as `YYYYMMDD`. A version introduced on 4 September 2025 is `20250904`. To target one, send the `Accept-Version` header on each request: ```http GET /accounts HTTP/1.1 Host: api.tastyworks.com Authorization: Bearer User-Agent: my-custom-client/1.0 Accept-Version: 20250904 ``` ## Requesting a version that no longer exists You get an HTTP **406**: ```json { "error": { "code": 406, "message": "The requested version is not supported." } } ``` For example, targeting `20240829` once it has been removed returns the above, even though later versions exist. In order-api, a header that falls between two existing versions is served the highest existing version at or below it. With `20250813` and `20261012` both live, `20260101` is served `20250813`. Only a header older than every existing version gets the 406. ## Deprecation window When a new version is introduced, older versions are deprecated. **A deprecated version has at least 6 months to live** from the point of deprecation. If you pin a version, plan to move forward before its window closes — otherwise the first sign of trouble is a 406 in production. ## Finding the available versions The [API Reference](/reference) has no version selector, and its pages do not state which version they describe, so don't read a page as confirmation that a given `Accept-Version` value is still accepted. Deprecation is only partly visible in the reference. The OpenAPI files carry a `deprecated` flag on some operations, but the reference pages do not display it. A page shows a deprecation only where the endpoint's description says so in words. `GET /instruments/future-option-products/{root_symbol}` is an example of both: the operation carries the flag and its description says so. [Release notes](/docs/release-notes) lists notable API changes under date headings, newest first. It is not a complete list of versions, and it has no deprecation notice for each deprecated endpoint, so don't rely on it alone to know which version or endpoint is deprecated. ## Related - [Release notes](/docs/release-notes) — notable API changes, newest first. - [API Reference](/reference) — endpoint documentation (no version selector). - [Error handling](/docs/guides/error-handling) — mapping status codes to fixes. - [OAuth2](/docs/authentication/oauth2) — the other headers every request needs. ## Related - [Release Notes](https://developer.tastytrade.com/docs/release-notes.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Error handling](https://developer.tastytrade.com/docs/guides/error-handling.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) --- # Release Notes Changes to the API, newest first. See [API versions](/docs/concepts/api-versions) for how to target a version with the `Accept-Version` header. ## 20261012 This release is for **order-api** only (the order endpoints). Order searches now **require a start date**, and customer live orders are now **paginated**. Order-api version `20250813` is **deprecated** and will be removed on or after **12 April 2027**. ### Breaking changes - `GET /accounts/{account_number}/orders` and `GET /customers/{customer_id}/orders` require `start-date` or `start-at`. Requests with neither return a **400**. - `GET /customers/{customer_id}/orders/live` is paginated: `per-page` (default 100, maximum 200) and `page-offset`, with a top-level `pagination` block in the response. In `20250813` it is not paginated and returns every order in one response. ### Migrating - Send `Accept-Version: 20261012`. A request with **no** `Accept-Version` header is currently served `20250813`, the oldest order-api version, and does not get the changes above. Set the header explicitly rather than relying on the default. - Add `start-date` (`YYYY-MM-DD`) or `start-at` (ISO 8601) to order searches. - To list today's orders without a date range, use `GET /accounts/{account_number}/orders/live`. It returns orders from the current trading day, in any status rather than only `Live`, and accepts `status` (several values at once) and `underlying-symbol` filters. - Page through customer live orders. Fetch the first page, and only request more if you need them. See [Pagination and filtering](/docs/guides/pagination-and-filtering) and [Orders](/reference/orders). ## 20260629 Cryptocurrency trading has been **disabled through the API** until further notice. ## 20260211 Legacy `/sessions` authentication has been **fully decommissioned**. If you are still sending `POST /sessions`, your application is failing to log in. Switch to [OAuth2](/docs/authentication/oauth2) to restore access. ## 20250813 Response data is now **paginated** for: - `GET /accounts/{account_number}/orders/live` ```json { "data": { "items": [{}] }, "pagination": { "per-page": 1000, "page-offset": 0, "item-offset": 0, "total-items": 25719, "total-pages": 26, "current-item-count": 1000 } } ``` See [Pagination and filtering](/docs/guides/pagination-and-filtering) for how to walk the pages, and [Orders](/reference/orders) for the endpoint itself. ## Related - [API versions](/docs/concepts/api-versions) — how versioning and deprecation work. - [OAuth2](/docs/authentication/oauth2) — the replacement for `/sessions`. - [Pagination and filtering](/docs/guides/pagination-and-filtering) — handling paginated responses. - [API Reference](/reference) — current endpoint documentation. ## Related - [API Versions](https://developer.tastytrade.com/docs/concepts/api-versions.md) - [OAuth2 authentication](https://developer.tastytrade.com/docs/authentication/oauth2.md) - [Pagination & filtering](https://developer.tastytrade.com/docs/guides/pagination-and-filtering.md) - [Quickstart](https://developer.tastytrade.com/docs/get-started.md) --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # Error reference Errors return an `error` object with `code` and `message`. Branch on the code; back off on 429. Each entry's anchor is its doc_url: `/reference/errors#`. ## Bad Request {#400} **Causes:** - Malformed JSON, or a body that doesn't match the endpoint schema. - Missing required fields, or wrong types/param names (keys are dasherized). **Fix:** Validate the request against the endpoint's schema in the API Reference. Ensure valid JSON and dasherized keys. ## Unauthorized {#401} **Causes:** - Missing `Authorization` header, or an expired/invalid access token (tokens last 15 minutes). - Invalid username/password at login. - Missing or malformed `User-Agent` header — tastytrade requires the format `/`; otherwise it returns 401. **Fix:** Send a valid `Authorization: Bearer ` (refresh every 15 minutes) AND always set a `User-Agent` like `my-app/1.0`. ## Forbidden {#403} **Causes:** - Authenticated, but the token's scope or the account authority doesn't permit this action. **Fix:** Check your OAuth scopes and the account's authority level for the operation. ## Not Found {#404} **Causes:** - Unknown resource — wrong account number, symbol, or order id. - Wrong base URL / environment (sandbox vs production). **Fix:** Verify the path and identifiers, and confirm the environment: sandbox `api.cert.tastyworks.com` vs production `api.tastyworks.com`. ## Unprocessable Entity {#422} **Causes:** - The action is invalid in context. For orders, a rejection returns 422 with a reason in the response JSON's `error.message`. **Fix:** Read `error.message`. For orders, run the dry-run first and fix the rejection reason before submitting. ## Too Many Requests {#429} **Causes:** - Request rate exceeded reasonable thresholds. **Fix:** Back off exponentially and reduce request rate. For market data, use the DXLink streamer instead of polling. Separately (a related but distinct symptom): repeated failed logins trigger an IP block that surfaces as connection timeouts, not 429s — it typically lasts ~8 hours; contact api.support@tastytrade.com to be unblocked. ## Server Error (HTTP 5xx) {#500} **Causes:** - An unexpected error on tastytrade's side. **Fix:** Retry with exponential backoff. If it persists, contact api.support@tastytrade.com with the request details. ## `unauthorized` (HTTP 401) {#unauthorized} **Causes:** - No valid access token. Access tokens last 15 minutes and must be sent on every request. **Fix:** Generate an access token and include it in the `Authorization` header on every request. ## `invalid_credentials` (HTTP 401) {#invalid_credentials} **Causes:** - Wrong username/password at login — often caused by using sandbox credentials against production (or vice versa); each environment has separate credentials. **Fix:** Confirm you're using the correct credentials for the environment you're hitting (sandbox vs production). ## `unconfirmed_user` (HTTP 401) {#unconfirmed_user} **Causes:** - The user account has not completed confirmation/onboarding. **Fix:** Ensure the (sandbox) customer/account is fully created and confirmed. See the FAQ, or contact api.support@tastytrade.com. ## `not_permitted` (HTTP 403) {#not_permitted} **Causes:** - Authenticated, but not authorized to access this resource — for example, requesting data for an account that belongs to a different customer. The message is `User not permitted access`. **Fix:** Verify the account number belongs to the authenticated user and that your credentials permit the operation. ## `preflight_check_failure` (HTTP 422) {#preflight_check_failure} **Causes:** - An order failed one or more preflight validations and was rejected. The specific failures are nested in `error.errors[]`, each with its own `code` and `message` (e.g. `cant_buy_for_credit`). **Fix:** Read each entry in `error.errors[]` and fix the order accordingly. Run the dry-run endpoint first to catch rejections before submitting. ## `cannot_update_order` (HTTP 422) {#cannot_update_order} **Causes:** - Cancellation was requested for an order that is already in a terminal status, so it can no longer be cancelled. The message is `the order could not be cancelled`. **Fix:** Fetch the order's current status before requesting cancellation; orders in a terminal status (e.g. `Filled`, `Cancelled`, `Rejected`) cannot be cancelled. See the Order Flow guide for terminal statuses. ## `cant_buy_for_credit` (HTTP 422) {#cant_buy_for_credit} **Causes:** - A buy order was submitted with `"price-effect": "Credit"`, which is not allowed. This code appears nested in `error.errors[]` under a `preflight_check_failure`. **Fix:** Set `price-effect` to `Debit` for orders that cost money to place and resubmit. Run the dry-run endpoint first to catch this before submitting. ## Preflight errors and warnings {#preflight-errors} An order that fails preflight returns `preflight_check_failure` (HTTP 422) with each failure in `error.errors[]`. Entries marked warning are different: they never appear in that 422. They come back in `data.warnings[]` of a successful response (a dry-run or a placed order) and do not block the order. Branch on `code`; messages are shown as the order service returns them, with `%{name}` standing for a value filled in at runtime. Where several messages are listed under one code, the service returns that code with any of them. This list is partial. Other preflight codes can be returned that are not listed here, so handle an unrecognised `code` by falling back to the `message`. ### Account, approval and buying power - `closing_only_check_failed` (error): Account is set to closing only and this order has an opening leg. {#closing_only_check_failed} - `restricted_position_check_failed` (error): A portion of this position is frozen. This may be due to pending transfers. Please contact the trade desk if you have any questions. {#restricted_position_check_failed} - `restricted_symbol_for_foreign_customers` (error): %{symbol} is a restricted symbol for customers residing outside of the USA. {#restricted_symbol_for_foreign_customers} - `margin_check_failed_with_flags` (error): Account does not have sufficient buying power available for this order due to %{risk_flags}. {#margin_check_failed_with_flags} - `delta_risk_check_failed` (error): Excessive risk - Consider an order that will reduce delta exposure. {#delta_risk_check_failed} - `net_liq_ratio_error` (error): Cash balance cannot exceed 15 times net liq. {#net_liq_ratio_error} - `margin_check_failed` (error): Your account does not have sufficient buying power available for this order. Please deposit funds or reduce the order size to place this. {#margin_check_failed} - `risk_check_failed` (error): Your account is not approved for spreads. Please check our help section to confirm the account types that support this. {#risk_check_failed} - Other message under this code: Your account is not approved for selling uncovered options. Please check our help section to confirm the account types that support this. - Other message under this code: Selling uncovered calls is not enabled for this account. Please check our help section to confirm the account types that support this. - Other message under this code: Account only approved for long equity positions - Other message under this code: Account cannot sell uncovered calls on this underlying - Other message under this code: Account cannot sell uncovered calls on underlyings with price below %{threshold} - `short_sell_not_allowed` (error): Your account is not approved for selling stock short. Please check our help section to confirm the account types that support this. {#short_sell_not_allowed} ### Price and market - `cant_buy_for_credit` (error): You cannot buy for a credit. - `cant_sell_for_debit` (error): You cannot sell for a debit. {#cant_sell_for_debit} - `zero_price_not_allowed` (error): Order price is invalid for this trade. You cannot place an order with 0.00 price. {#zero_price_not_allowed} - `invalid_fractional_price` (warning): Order price resolution must not be smaller than a penny. {#invalid_fractional_price} - `invalid_order_price` (error): Order price is invalid for this trade. Contact trade desk with any questions {#invalid_order_price} - `invalid_price_increment` (error): Price must be in increments of $%{increment} for this order. {#invalid_price_increment} - `limit_like_orders_require_price` (error): Limit like orders require a price. {#limit_like_orders_require_price} - `order_limit_price_overflow` (error): Order limit price exceeds the maximum price allowed. Please reduce the price to proceed. {#order_limit_price_overflow} - `order_must_omit_price` (error): This order can not be submitted with an associated price. {#order_must_omit_price} - `spread_market_order_check_failed` (error): Orders with 2 or more legs cannot be placed as "Market" orders. {#spread_market_order_check_failed} - `spread_width_price_check_failed` (error): Order price is greater than spread width. {#spread_width_price_check_failed} - `unfavorable_price` (error): Unfavorable price - Consider limit at or better than strike {#unfavorable_price} - `marketable_limit_price_error` (error): No suitable price found for the marketable limit order. Please consider routing a limit order. {#marketable_limit_price_error} - `marketable_limit_instrument_not_allowed` (error): Marketable limit orders can only be routed for multi-leg options and covered stock. {#marketable_limit_instrument_not_allowed} - `no_bid_or_ask` (warning): One or more legs in this order do not have a bid or ask. {#no_bid_or_ask} - `no_quote_found` (error): Unable to route order. No quote found. {#no_quote_found} ### Order structure - `cash_settled_equity_invalid` (error): Orders may not contain an equity leg for a cash settled index. (There is no actual instrument to trade). {#cash_settled_equity_invalid} - `duplicate_order_leg_symbols` (error): Order legs cannot have duplicate symbols. {#duplicate_order_leg_symbols} - `illegal_buy_and_sell_on_same_symbol` (error): Cannot buy and sell against the same symbol. {#illegal_buy_and_sell_on_same_symbol} - `invalid_combined_option_stock_amount` (error): Order contains equity leg and more than one option leg {#invalid_combined_option_stock_amount} - `multiple_equity_legs_invalid` (error): Orders may not have multiple equity legs. {#multiple_equity_legs_invalid} - `invalid_symbol` (error): This order contains a leg with an invalid symbol. {#invalid_symbol} - `order_leg_must_have_quantity` (error): Order Legs for this order type must have a quantity. {#order_leg_must_have_quantity} - `cannot_close_more_than_existing_position` (error): You cannot close more than %{quantity} for %{symbol}. {#cannot_close_more_than_existing_position} - `closing_with_no_position` (warning): You cannot route a closing order without an existing position to close. This order will be updated to a %{open_close} order when routed. Fractional equity and cryptocurrency orders can also return this code as an error, with a different message. {#closing_with_no_position} - `closing_with_no_position_error` (error): You cannot route a closing order without an existing position to close. {#closing_with_no_position_error} - `too_close_to_expiration` (error): Sell to open orders cannot be sent %{interval} prior to market close on day of expiration. {#too_close_to_expiration} - `qty_greater_than_zero` (error): Orders with a leg remaining must have a remaining quantity greater than zero. {#qty_greater_than_zero} - `closing_only` (error): %{symbol} is currently set to closing only. Only closing trades may be submitted at this time. {#closing_only} - Other message under this code: This expiration cycle for %{symbol} is now closing only. Please close your position or roll it to the active expiration - `duplicate_closing_order` (error): You already have a closing order for %{symbol} which must be canceled before this order can be routed. Only fractional equity and cryptocurrency orders return this code. Other orders get cannot_close_against_more_than_existing_position with the same message instead, and fractional equity and cryptocurrency orders can return that code too, so handle both. {#duplicate_closing_order} - `cannot_close_against_more_than_existing_position` (error): You already have a closing order for %{symbol} which must be canceled before this order can be routed. {#cannot_close_against_more_than_existing_position} - `illegal_open_or_close_against_long_position` (warning): You cannot %{action} against a %{direction} position. This order will be updated to a %{open_close} order when routed. Dry-run only. An order that sets advanced-instructions.strict-position-effect-validation gets the _error code instead, as an error. {#illegal_open_or_close_against_long_position} - `illegal_open_or_close_against_short_position` (warning): You cannot %{action} against a %{direction} position. This order will be updated to a %{open_close} order when routed. Dry-run only. An order that sets advanced-instructions.strict-position-effect-validation gets the _error code instead, as an error. {#illegal_open_or_close_against_short_position} - `illegal_open_or_close_against_long_position_error` (error): You cannot %{action} against a %{direction} position. Returned only when the order sets advanced-instructions.strict-position-effect-validation. {#illegal_open_or_close_against_long_position_error} - `illegal_open_or_close_against_short_position_error` (error): You cannot %{action} against a %{direction} position. Returned only when the order sets advanced-instructions.strict-position-effect-validation. {#illegal_open_or_close_against_short_position_error} - `invalid_action` (error): Opening orders with non standard options are not supported. {#invalid_action} ### Complex orders - `invalid_complex_complexity` (error): Complex order limit hit for %{underlying_symbol} {#invalid_complex_complexity} - `invalid_complex_structure` (error): Complex order structure is invalid {#invalid_complex_structure} - `invalid_complex_tif` (error): A complex order with a GTC trigger order may not have dependent orders with a time in force of Day {#invalid_complex_tif} - `invalid_complex_underlying` (error): Complex orders must share an underlying symbol {#invalid_complex_underlying} - `invalid_complex_fractional` (error): Complex orders for this instrument type cannot have fractional quantities {#invalid_complex_fractional} - `invalid_complex_cryptocurrency` (error): Only conditional complex orders are supported for this instrument type {#invalid_complex_cryptocurrency} - `invalid_triggered_order_price` (error): Order price is invalid for this trade. {#invalid_triggered_order_price} - `pairs_trade` (warning): Pairs orders have additional execution risk as each order routes separately with price type market. {#pairs_trade} ### Futures - `cfe_stop_future_order_not_allowed` (error): Stop market orders for %{underlying_symbol} are not allowed by the CFE. {#cfe_stop_future_order_not_allowed} - `cfe_market_order_not_allowed` (error): Market orders only allowed during regular trading hours by the CFE. {#cfe_market_order_not_allowed} - `cfe_multiple_legs_not_allowed` (error): Multi leg orders are not supported for CFE products. {#cfe_multiple_legs_not_allowed} - `future_option_too_close_to_expiration` (error): Future option opening trades cannot be placed %{interval} prior to market close on day of expiration. {#future_option_too_close_to_expiration} - `insufficient_net_liquid_value` (error): A minimum net liquidating value of $%{net_liq} is required to open this new futures positions. {#insufficient_net_liquid_value} - `invalid_futures_fractional_price` (error): Fractionally price futures must be submitted in decimal format. {#invalid_futures_fractional_price} - `invalid_strategy` (error): This strategy type is not supported. Try legging in. {#invalid_strategy} - `instrument_not_tradeable` (error): This is not a tradeable product. {#instrument_not_tradeable} - `only_limit_future_spread_orders_allowed` (error): Only limit orders are allowed for future spreads. {#only_limit_future_spread_orders_allowed} - `stop_future_option_order_not_allowed` (error): Stop market and stop limit future option orders are not allowed. {#stop_future_option_order_not_allowed} - `unable_to_accept_cancel` (error): Unable to cancel order. %{instrument_collection} markets are not currently accepting them. {#unable_to_accept_cancel} - `unable_to_cancel_past_stops_trading_at` (error): Unable to cancel order. %{instrument} is no longer trading. {#unable_to_cancel_past_stops_trading_at} - `order_not_allowed` (error): This order cannot be placed right now. Contact trade desk with any questions {#order_not_allowed} - `futures_not_allowed` (error): Your account is not approved for futures trading. Please enable futures trading to place this trade. {#futures_not_allowed} ### Time in force - `invalid_gtd_expiration_date` (error): The GTD date is past the option expiration. {#invalid_gtd_expiration_date} - `past_gtd_date` (error): GTD date cannot be in the past. {#past_gtd_date} - `tif.not_routable` (error): Order cannot be routed at this time. {#tif.not_routable} - `tif.day_invalid_intersession` (error): Day orders will be accepted after 3:15pm CT. Consider EXT to route now. {#tif.day_invalid_intersession} - `tif.next_valid_session` (warning): Your order will begin working during next valid session. Also returned in warnings[] when the order is placed, not only on a dry-run. {#tif.next_valid_session} - `tif.futures_invalid` (error): This time in force value is not supported for futures trades. {#tif.futures_invalid} - `tif.futures_session_not_active` (error): The Futures trading session is not currently active. {#tif.futures_session_not_active} - `tif.cryptocurrency_invalid` (error): This time in force value is not supported for cryptocurrency trades with this order type. {#tif.cryptocurrency_invalid} - `tif_single_leg_equities_only` (error): Orders with a time in force of %{time_in_force} must only include a single Equity instrument. {#tif_single_leg_equities_only} - `tif_limit_orders_only` (error): Orders with a time in force of %{time_in_force} must be Limit or Stop Limit orders. {#tif_limit_orders_only} - `tif_no_after_hours_orders` (error): EXT orders can only be routed between %{start_time} and %{end_time} Central, and on market half days between %{start_time} and %{half_day_end_time} Central. EXT trading is closed on market holidays. {#tif_no_after_hours_orders} - Other message under this code: Overnight orders can only be routed during market days or during the overnight hours prior to a market day. - `tif_no_after_hours_opening_market_orders` (error): Opening market orders not allowed when market closed. {#tif_no_after_hours_opening_market_orders} - `tif_no_stop_market_gtc_options` (error): Stop Market Equity Option orders cannot be GTC or GTD {#tif_no_stop_market_gtc_options} ### Limits - `order_limit_check_failed` (error): Order size exceeds the limit. Contact the trade desk to increase your limits. {#order_limit_check_failed} - `position_limit_check_failed` (error): Resulting position size exceeds the limit. Contact the trade desk to increase your limits. {#position_limit_check_failed} - `underlying_opening_order_limit_check_failed` (error): Number of opening orders for underlying exceeds the limit. Contact the trade desk to increase your limits. {#underlying_opening_order_limit_check_failed} --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/trading-status — Get Account Trading Status Returns the current trading status for an account, reporting whether and how it may trade. If `is-closed` or `is-frozen` is true, trading is blocked entirely; if `is-closing-only` (or `is-cryptocurrency-closing-only` / `is-futures-closing-only`) is true, only closing trades are allowed, and `is-risk-reducing-only` restricts the account to de-risking activity. The response also exposes per-feature toggles, the live `day-trade-count`, the `options-level` tier, and margin-call flags. Check trading status before building order flows so restrictions surface up front rather than as rejected orders. **Group:** Account Status · **operationId:** `getAccountsAccountNumberTradingStatus` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `200` — The account's current trading status. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. Send a valid `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` in the form `/`. Note that `User-Agent` rejections are returned as an HTML error page from the edge, not the JSON error envelope. - `403` — Authenticated, but the token's scope or the account authority does not permit reading this account's trading status. - `404` — No account exists for the supplied `account_number`. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/trading-status", "method": "get", "operation": { "description": "Returns the current trading status for an account, reporting whether and how it may trade. If `is-closed` or `is-frozen` is true, trading is blocked entirely; if `is-closing-only` (or `is-cryptocurrency-closing-only` / `is-futures-closing-only`) is true, only closing trades are allowed, and `is-risk-reducing-only` restricts the account to de-risking activity. The response also exposes per-feature toggles, the live `day-trade-count`, the `options-level` tier, and margin-call flags. Check trading status before building order flows so restrictions surface up front rather than as rejected orders.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "The account's current trading status.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/TradingStatus" }, "context": { "type": "string", "example": "/accounts/{account_number}/trading-status" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header. Send a valid `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` in the form `/`. Note that `User-Agent` rejections are returned as an HTML error page from the edge, not the JSON error envelope.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account authority does not permit reading this account's trading status.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account exists for the supplied `account_number`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "trading-status" ], "operationId": "getAccountsAccountNumberTradingStatus", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account Trading Status" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /api-quote-tokens — Get API Quote Token Returns the streamer endpoint, entitlement level, and identification token the current customer needs to subscribe to real-time market data over the DXLink streamer. The token identifies the customer to tastytrade's quote provider, DXLink, and is valid for 24 hours. Call this before opening a quote streamer connection. **Group:** Accounts and Customers · **operationId:** `getApiQuoteTokens` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `200` — The DXLink streamer URL, entitlement level, and a quote token for the current customer. Quote streamer tokens are valid for 24 hours. - `401` — Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token (refresh every 15 minutes) and a User-Agent like my-app/1.0. - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/api-quote-tokens", "method": "get", "operation": { "description": "Returns the streamer endpoint, entitlement level, and identification token the current customer needs to subscribe to real-time market data over the DXLink streamer. The token identifies the customer to tastytrade's quote provider, DXLink, and is valid for 24 hours. Call this before opening a quote streamer connection.", "responses": { "200": { "description": "The DXLink streamer URL, entitlement level, and a quote token for the current customer. Quote streamer tokens are valid for 24 hours.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/QuoteStreamerTokenAuthResult" }, "context": { "type": "string", "example": "/api-quote-tokens" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token (refresh every 15 minutes) and a User-Agent like my-app/1.0.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "api-quote-tokens" ], "operationId": "getApiQuoteTokens", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get API Quote Token" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /customers/{customer_id} — Get Customer Returns the full customer resource, including name, addresses, suitability profile, and personal or entity details. For simplicity and security the customer's internal identifier is not exposed: pass `me` as the `customer_id` to fetch the customer linked to the current access token. Set `allow-missing=true` to avoid a 404 when the customer does not exist. **Group:** Accounts and Customers · **operationId:** `getCustomersCustomerId` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `customer_id` (path, required) — Only a value of `me` is allowed. The API does not expose customers' internal identifiers. - `allow-missing` (query) — Does not raise a 404 if customer is missing ## Responses - `200` — The full customer resource for the requested customer. - `401` — Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0. - `404` — No customer matches the supplied customer_id. Pass `me` to resolve the current customer, or set allow-missing=true to suppress this error. - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/customers/{customer_id}", "method": "get", "operation": { "description": "Returns the full customer resource, including name, addresses, suitability profile, and personal or entity details. For simplicity and security the customer's internal identifier is not exposed: pass `me` as the `customer_id` to fetch the customer linked to the current access token. Set `allow-missing=true` to avoid a 404 when the customer does not exist.", "parameters": [ { "in": "path", "name": "customer_id", "required": true, "schema": { "type": "string", "format": "int32" }, "example": "me", "description": "Only a value of `me` is allowed. The API does not expose customers' internal identifiers." }, { "in": "query", "name": "allow-missing", "description": "Does not raise a 404 if customer is missing", "required": false, "schema": { "type": "boolean", "default": false }, "example": true } ], "responses": { "200": { "description": "The full customer resource for the requested customer.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Customer" }, "context": { "type": "string", "example": "/customers/{customer_id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No customer matches the supplied customer_id. Pass `me` to resolve the current customer, or set allow-missing=true to suppress this error.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "customers" ], "operationId": "getCustomersCustomerId", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Customer" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /customers/{customer_id}/accounts — List Customer Accounts Returns every account the current customer has access to, each wrapped with the customer's authority level over it. After authenticating, this is typically the first call a client makes to discover account numbers for subsequent requests. Authority levels are `owner` (full privileges), `trade-only` (can trade but not move cash), and `read-only` (GET access only). Pass `me` as the `customer_id`. **Group:** Accounts and Customers · **operationId:** `getCustomersCustomerIdAccounts` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `customer_id` (path, required) — Only a value of `me` is allowed. The API does not expose customers' internal identifiers. ## Responses - `200` — A list of the accounts the customer can access, each with its authority level. - `401` — Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0. - `404` — No customer matches the supplied customer_id. Pass `me` to resolve the current customer. - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/customers/{customer_id}/accounts", "method": "get", "operation": { "description": "Returns every account the current customer has access to, each wrapped with the customer's authority level over it. After authenticating, this is typically the first call a client makes to discover account numbers for subsequent requests. Authority levels are `owner` (full privileges), `trade-only` (can trade but not move cash), and `read-only` (GET access only). Pass `me` as the `customer_id`.", "parameters": [ { "in": "path", "name": "customer_id", "required": true, "schema": { "type": "string", "format": "int32" }, "example": "me", "description": "Only a value of `me` is allowed. The API does not expose customers' internal identifiers." } ], "responses": { "200": { "description": "A list of the accounts the customer can access, each with its authority level.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/AccountAuthorityDecorator" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/customers/{customer_id}/accounts" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No customer matches the supplied customer_id. Pass `me` to resolve the current customer.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "customers" ], "operationId": "getCustomersCustomerIdAccounts", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Customer Accounts" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /customers/{customer_id}/accounts/{account_number} — Get Account Returns a single account resource by account number for the given customer. Use the account numbers returned by the list-accounts endpoint. Pass `me` as the `customer_id` to scope the lookup to the current customer. **Group:** Accounts and Customers · **operationId:** `getCustomersCustomerIdAccountsAccountNumber` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `customer_id` (path, required) — Only a value of `me` is allowed. The API does not expose customers' internal identifiers. - `account_number` (path, required) — The account number of the account. ## Responses - `200` — The full account resource for the requested account number. - `401` — Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0. - `404` — No account matches the supplied account_number for this customer. Verify the account number and that you are using the correct environment (sandbox vs production). - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/customers/{customer_id}/accounts/{account_number}", "method": "get", "operation": { "description": "Returns a single account resource by account number for the given customer. Use the account numbers returned by the list-accounts endpoint. Pass `me` as the `customer_id` to scope the lookup to the current customer.", "parameters": [ { "in": "path", "name": "customer_id", "required": true, "schema": { "type": "string", "format": "int32" }, "example": "me", "description": "Only a value of `me` is allowed. The API does not expose customers' internal identifiers." }, { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234", "description": "The account number of the account." } ], "responses": { "200": { "description": "The full account resource for the requested account number.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Account" }, "context": { "type": "string", "example": "/customers/{customer_id}/accounts/{account_number}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed User-Agent header. Send a valid Authorization: Bearer token and a User-Agent like my-app/1.0.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No account matches the supplied account_number for this customer. Verify the account number and that you are using the correct environment (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "customers" ], "operationId": "getCustomersCustomerIdAccountsAccountNumber", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /available-dates — List Available Date Ranges Returns each symbol with historical backtest data alongside the `startDate` and `endDate` of its available coverage. Call this before creating a backtest to confirm a symbol has history for your requested window. **Group:** Backtesting · **operationId:** `getAvailableDates` ## Parameters _None_ ## Responses - `200` — An array of symbols, each with the inclusive range of dates that have backtest history. - `400` — The request was malformed. - `401` — Unauthorized. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. - `500` — # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/available-dates", "method": "get", "operation": { "summary": "List Available Date Ranges", "description": "Returns each symbol with historical backtest data alongside the `startDate` and `endDate` of its available coverage. Call this before creating a backtest to confirm a symbol has history for your requested window.", "operationId": "getAvailableDates", "responses": { "200": { "description": "An array of symbols, each with the inclusive range of dates that have backtest history.", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AvailableSymbolDates" } } } } }, "400": { "$ref": "#/components/responses/400", "description": "The request was malformed." }, "401": { "description": "Unauthorized." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." }, "500": { "$ref": "#/components/responses/500" } }, "tags": [ "backtesting" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /backtests — List Your Backtests Returns the IDs of every backtest the authenticated user has submitted. Use an ID with `GET /backtests/{id}` to poll status or read results. **Group:** Backtesting · **operationId:** `getUsersBacktests` ## Parameters _None_ ## Responses - `200` — An array of backtest IDs belonging to the current user. - `401` — Unauthorized. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/backtests", "method": "get", "operation": { "summary": "List Your Backtests", "description": "Returns the IDs of every backtest the authenticated user has submitted. Use an ID with `GET /backtests/{id}` to poll status or read results.", "operationId": "getUsersBacktests", "responses": { "200": { "description": "An array of backtest IDs belonging to the current user.", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string" } } } } }, "401": { "description": "Unauthorized." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." } }, "tags": [ "backtesting" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /backtests — Create A Backtest Submits a backtest definition (underlying `symbol`, a `startDate`/`endDate` window, and one or more `legs`) and starts the run. A `201` means the backtest is pending and still running; a `200` means it is already completed. Either way the body includes an `id` to poll with `GET /backtests/{id}`. **Group:** Backtesting · **operationId:** `postBacktests` ## Parameters _None_ ## Responses - `200` — Backtest completed and ready to read. The body is a fully populated backtest object. - `201` — Backtest accepted and still running. Poll `GET /backtests/{id}` and watch `status` until it reaches `completed`. - `400` — The request body was malformed or did not match the backtest schema (for example a missing required leg field or an invalid `strikeSelection` value). - `401` — Unauthorized. - `404` — Backtest not found. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. - `500` — # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/backtests", "method": "post", "operation": { "summary": "Create A Backtest", "description": "Submits a backtest definition (underlying `symbol`, a `startDate`/`endDate` window, and one or more `legs`) and starts the run. A `201` means the backtest is pending and still running; a `200` means it is already completed. Either way the body includes an `id` to poll with `GET /backtests/{id}`.", "operationId": "postBacktests", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestPost" } } } }, "responses": { "200": { "description": "Backtest completed and ready to read. The body is a fully populated backtest object.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "201": { "description": "Backtest accepted and still running. Poll `GET /backtests/{id}` and watch `status` until it reaches `completed`.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "400": { "$ref": "#/components/responses/400", "description": "The request body was malformed or did not match the backtest schema (for example a missing required leg field or an invalid `strikeSelection` value)." }, "401": { "description": "Unauthorized." }, "404": { "$ref": "#/components/responses/404", "description": "Backtest not found." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." }, "500": { "$ref": "#/components/responses/500" } }, "tags": [ "backtesting" ], "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": false, "x-rate-limit-bucket": "write" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /backtests/{id} — Get Backtest By ID Fetches a single backtest by its ID. Poll this endpoint to watch `status` move through `pending`, `running`, and `completed`; while it runs the object reports `progress` and an `ETA` you can use to space out polls. Once `completed`, read `statistics`, `trials`, `snapshots`, and `notices`. **Group:** Backtesting · **operationId:** `getBacktests` ## Parameters - `id` (path, required) — ## Responses - `200` — The backtest object, including its current status and (once completed) results. - `400` — The supplied backtest ID was malformed. - `401` — Unauthorized. - `404` — No backtest exists with the supplied ID for this user. - `429` — Request rate exceeded reasonable thresholds. Poll on an interval rather than tightly looping, and back off on 429. - `500` — # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/backtests/{id}", "method": "get", "operation": { "summary": "Get Backtest By ID", "description": "Fetches a single backtest by its ID. Poll this endpoint to watch `status` move through `pending`, `running`, and `completed`; while it runs the object reports `progress` and an `ETA` you can use to space out polls. Once `completed`, read `statistics`, `trials`, `snapshots`, and `notices`.", "operationId": "getBacktests", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The backtest object, including its current status and (once completed) results.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BacktestGet" } } } }, "400": { "$ref": "#/components/responses/400", "description": "The supplied backtest ID was malformed." }, "401": { "description": "Unauthorized." }, "404": { "$ref": "#/components/responses/404", "description": "No backtest exists with the supplied ID for this user." }, "429": { "description": "Request rate exceeded reasonable thresholds. Poll on an interval rather than tightly looping, and back off on 429." }, "500": { "$ref": "#/components/responses/500" } }, "tags": [ "backtesting" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /backtests/{id}/cancel — Cancel A Running Backtest Stops a `pending` or `running` backtest early. Returns `204 No Content` on success. Useful for aborting a long run you no longer need. **Group:** Backtesting · **operationId:** `cancelBacktests` ## Parameters - `id` (path, required) — ## Responses - `204` — The backtest was cancelled. No response body is returned. - `400` — The supplied backtest ID was malformed. - `401` — Unauthorized. - `404` — No backtest exists with the supplied ID for this user. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/backtests/{id}/cancel", "method": "post", "operation": { "summary": "Cancel A Running Backtest", "description": "Stops a `pending` or `running` backtest early. Returns `204 No Content` on success. Useful for aborting a long run you no longer need.", "operationId": "cancelBacktests", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "The backtest was cancelled. No response body is returned." }, "400": { "$ref": "#/components/responses/400", "description": "The supplied backtest ID was malformed." }, "401": { "description": "Unauthorized." }, "404": { "$ref": "#/components/responses/404", "description": "No backtest exists with the supplied ID for this user." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." } }, "tags": [ "backtesting" ], "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": false, "x-rate-limit-bucket": "write" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /backtests/{id}/logs — Get Backtest Logs Returns the step-by-step execution logs for the specified backtest, useful for understanding how trials were opened and closed during the run. **Group:** Backtesting · **operationId:** `getBacktestsLogs` ## Parameters - `id` (path, required) — ## Responses - `200` — The execution log for the backtest. - `400` — The supplied backtest ID was malformed. - `401` — Unauthorized. - `404` — No backtest exists with the supplied ID for this user. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/backtests/{id}/logs", "method": "get", "operation": { "summary": "Get Backtest Logs", "description": "Returns the step-by-step execution logs for the specified backtest, useful for understanding how trials were opened and closed during the run.", "operationId": "getBacktestsLogs", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The execution log for the backtest." }, "400": { "$ref": "#/components/responses/400", "description": "The supplied backtest ID was malformed." }, "401": { "description": "Unauthorized." }, "404": { "$ref": "#/components/responses/404", "description": "No backtest exists with the supplied ID for this user." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." } }, "tags": [ "backtesting" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /simulate-trade — Simulate A Single Trade Returns historical pricing for one trade without defining a full backtest. Supply an `underlying` and one or more `legs` (each leg uses tastytrade/OCC symbology), optionally bounded by `startTime`/`endTime`. The response is a time series of price points with the trade `effect` (debit or credit), `underlyingPrice`, and `delta`. **Group:** Backtesting · **operationId:** `simulateTrade` ## Parameters _None_ ## Responses - `200` — A time-ordered series of price points for the simulated trade. - `400` — The request body was malformed, for example an invalid leg `symbol` or `direction`. - `401` — Unauthorized. - `404` — No history is available for the requested underlying or time range. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/simulate-trade", "method": "post", "operation": { "summary": "Simulate A Single Trade", "description": "Returns historical pricing for one trade without defining a full backtest. Supply an `underlying` and one or more `legs` (each leg uses tastytrade/OCC symbology), optionally bounded by `startTime`/`endTime`. The response is a time series of price points with the trade `effect` (debit or credit), `underlyingPrice`, and `delta`.", "operationId": "simulateTrade", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "underlying": { "type": "string", "description": "Underlying symbol of the trade" }, "startTime": { "type": "string", "format": "date-time", "description": "Optionally, start time of the trade in ISO 8601 format." }, "endTime": { "type": "string", "format": "date-time", "description": "Optionally, end time of the trade in ISO 8601 format." }, "legs": { "type": "array", "items": { "type": "object", "properties": { "symbol": { "type": "string", "description": "The leg symbol uses the tastytrade / OCC symbology convention - https://developer.tastytrade.com/api-overview/#tastytrade-symbology" }, "direction": { "type": "string", "enum": [ "long", "short" ] }, "quantity": { "type": "integer" } } } } } }, "examples": { "coveredCall": { "summary": "Covered call", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227C00275000", "direction": "short", "quantity": 1 }, { "symbol": "SPY", "direction": "long", "quantity": 100 } ] } }, "putRatioSpread": { "summary": "Put ratio spread", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227P00265000", "direction": "long", "quantity": 3 }, { "symbol": "SPY 190227P00275000", "direction": "short", "quantity": 1 } ] } }, "longCallButterfly": { "summary": "Long call butterfly", "value": { "underlying": "SPY", "legs": [ { "symbol": "SPY 190227C00270000", "direction": "long", "quantity": 2 }, { "symbol": "SPY 190227C00275000", "direction": "short", "quantity": 1 }, { "symbol": "SPY 190227C00265000", "direction": "short", "quantity": 1 } ] } } } } } }, "responses": { "200": { "description": "A time-ordered series of price points for the simulated trade.", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "object", "properties": { "dateTime": { "type": "string", "format": "date-time" }, "price": { "type": "string" }, "effect": { "type": "string", "enum": [ "debit", "credit" ] }, "underlyingPrice": { "type": "string" }, "delta": { "type": "string" } } } } } } }, "400": { "description": "The request body was malformed, for example an invalid leg `symbol` or `direction`." }, "401": { "description": "Unauthorized." }, "404": { "description": "No history is available for the requested underlying or time range." }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially before retrying." } }, "tags": [ "backtesting" ], "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": false, "x-rate-limit-bucket": "write" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/balance-snapshots — List Account Balance Snapshots Returns balance snapshots for an account; the response also includes the account's current balance object alongside the historical snapshots. A snapshot is captured twice a day: once in the morning (BOD) and once after the equities market closes (EOD). The required time-of-day parameter selects which snapshot. Optionally pass snapshot-date for a specific day, or start-date and end-date for a range; if no dates are given, the most recent snapshot is returned. Results are paginated via per-page and page-offset. **Group:** Balances and Positions · **operationId:** `getAccountsAccountNumberBalanceSnapshots` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `per-page` (query) — - `page-offset` (query) — - `currency` (query) — Currency - `snapshot-date` (query) — The day of the balance snapshot to retrieve - `time-of-day` (query, required) — The abbreviation for the time of day. - `start-date` (query) — The first date in a range of dates to retrieve - `end-date` (query) — The last date in a range of dates to retrieve - `account_number` (path, required) — ## Responses - `200` — A list of balance snapshots wrapped in a data.items array. The list also includes the account's current balance object alongside the historical snapshots. - `401` — Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request. - `403` — Authenticated, but the token's scope or the account's authority level does not permit reading balance snapshots for this account. - `404` — Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox vs production). - `422` — The query is invalid in context, for example a missing required time-of-day, or an invalid date or date range. Provide a valid time-of-day (BOD or EOD) and well-formed dates. - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/balance-snapshots", "method": "get", "operation": { "description": "Returns balance snapshots for an account; the response also includes the account's current balance object alongside the historical snapshots. A snapshot is captured twice a day: once in the morning (BOD) and once after the equities market closes (EOD). The required time-of-day parameter selects which snapshot. Optionally pass snapshot-date for a specific day, or start-date and end-date for a range; if no dates are given, the most recent snapshot is returned. Results are paginated via per-page and page-offset.", "parameters": [ { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 2000, "default": 250 }, "example": 10 }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "currency", "description": "Currency", "required": false, "schema": { "type": "string", "default": "USD" } }, { "in": "query", "name": "snapshot-date", "description": "The day of the balance snapshot to retrieve", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "time-of-day", "description": "The abbreviation for the time of day.", "required": true, "schema": { "type": "string", "enum": [ "EOD", "BOD" ] }, "example": "EOD" }, { "in": "query", "name": "start-date", "description": "The first date in a range of dates to retrieve", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "end-date", "description": "The last date in a range of dates to retrieve", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "A list of balance snapshots wrapped in a data.items array. The list also includes the account's current balance object alongside the historical snapshots.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/AccountBalanceSnapshot" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/balance-snapshots" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account's authority level does not permit reading balance snapshots for this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The query is invalid in context, for example a missing required time-of-day, or an invalid date or date range. Provide a valid time-of-day (BOD or EOD) and well-formed dates.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "balance-snapshots" ], "operationId": "getAccountsAccountNumberBalanceSnapshots", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Account Balance Snapshots" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/balances — Get Account Balances Returns the single current balance object for an account: cash, position values broken out by instrument type and side (for example long-equity-value, long-derivative-value, long-futures-value, long-cryptocurrency-value), buying power, margin requirements, and net-liquidating-value. Defaults to USD; pass currency to request a different currency balance. **Group:** Balances and Positions · **operationId:** `getAccountsAccountNumberBalances` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `currency` (query) — Currency balance to get for account - `account_number` (path, required) — ## Responses - `200` — The current balance object for the account, wrapped in data. - `401` — Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request. - `403` — Authenticated, but the token's scope or the account's authority level does not permit reading balances for this account. - `404` — Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox api.cert.tastyworks.com vs production api.tastyworks.com). - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/balances", "method": "get", "operation": { "description": "Returns the single current balance object for an account: cash, position values broken out by instrument type and side (for example long-equity-value, long-derivative-value, long-futures-value, long-cryptocurrency-value), buying power, margin requirements, and net-liquidating-value. Defaults to USD; pass currency to request a different currency balance.", "parameters": [ { "in": "query", "name": "currency", "description": "Currency balance to get for account", "required": false, "schema": { "type": "string", "default": "USD" } }, { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "The current balance object for the account, wrapped in data.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AccountBalance" }, "context": { "type": "string", "example": "/accounts/{account_number}/balances" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account's authority level does not permit reading balances for this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox api.cert.tastyworks.com vs production api.tastyworks.com).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberBalances", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account Balances" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/balances/{currency} — Get Account Balance By Currency Returns the current balance object for an account in a specific currency. Use this when an account holds more than one currency and you need the balance for one of them; for the default USD balance, the plural balances endpoint is sufficient. **Group:** Balances and Positions · **operationId:** `getAccountsAccountNumberBalancesCurrency` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `currency` (path, required) — - `account_number` (path, required) — ## Responses - `200` — The current balance object for the account in the requested currency, wrapped in data. - `401` — Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request. - `403` — Authenticated, but the token's scope or the account's authority level does not permit reading balances for this account. - `404` — Account or currency not found. Verify the account_number and currency, and confirm you are hitting the correct environment (sandbox vs production). - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/balances/{currency}", "method": "get", "operation": { "description": "Returns the current balance object for an account in a specific currency. Use this when an account holds more than one currency and you need the balance for one of them; for the default USD balance, the plural balances endpoint is sufficient.", "parameters": [ { "in": "path", "name": "currency", "required": true, "schema": { "type": "string" } }, { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "The current balance object for the account in the requested currency, wrapped in data.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/AccountBalance" }, "context": { "type": "string", "example": "/accounts/{account_number}/balances/{currency}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account's authority level does not permit reading balances for this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Account or currency not found. Verify the account_number and currency, and confirm you are hitting the correct environment (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberBalancesCurrency", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account Balance By Currency" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/positions — List Account Positions Returns the account's positions. A position with a quantity of 0 is considered closed and is purged overnight, so by default only open positions are returned; pass include-closed-positions to include them. Filter by symbol, underlying-symbol, instrument-type, or underlying-product-code, and use net-positions to group by instrument type and symbol. The endpoint does not return live profit/loss or a mark unless include-marks is set; for up-to-date P/L, combine the cost-basis fields here with live quote data from streaming market data. **Group:** Balances and Positions · **operationId:** `getAccountsAccountNumberPositions` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `underlying-symbol` (query) — An array of Underlying symbol(s) for positions (example: underlying-symbol[]={value1}&underlying-symbol[]={value2}) - `symbol` (query) — A single symbol. Stock Ticker Symbol `AAPL`, \ OCC Option Symbol `AAPL 191004P00275000`, \ TW Future Symbol `/ESZ9`, or \ TW Future Option Symbol `./ESZ9 EW4U9 190927P2975` - `instrument-type` (query) — The type of Instrument - `include-closed-positions` (query) — If closed positions should be included in the query - `underlying-product-code` (query) — The underlying Future's Product code. i.e `ES` - `partition-keys` (query) — Account partition keys (example: partition-keys[]={value1}&partition-keys[]={value2}) - `net-positions` (query) — Returns net positions grouped by instrument type and symbol - `include-marks` (query) — Include current quote mark (note: can decrease performance) - `account_number` (path, required) — ## Responses - `200` — A list of the account's positions, wrapped in a data.items array. - `401` — Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request. - `403` — Authenticated, but the token's scope or the account's authority level does not permit reading positions for this account. - `404` — Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox api.cert.tastyworks.com vs production api.tastyworks.com). - `429` — Request rate exceeded. Back off exponentially and reduce request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/positions", "method": "get", "operation": { "description": "Returns the account's positions. A position with a quantity of 0 is considered closed and is purged overnight, so by default only open positions are returned; pass include-closed-positions to include them. Filter by symbol, underlying-symbol, instrument-type, or underlying-product-code, and use net-positions to group by instrument type and symbol. The endpoint does not return live profit/loss or a mark unless include-marks is set; for up-to-date P/L, combine the cost-basis fields here with live quote data from streaming market data.", "parameters": [ { "in": "query", "name": "underlying-symbol", "description": "An array of Underlying symbol(s) for positions (example: underlying-symbol[]={value1}&underlying-symbol[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "AAPL" ] }, { "in": "query", "name": "symbol", "description": "A single symbol. Stock Ticker Symbol `AAPL`, \\\n OCC Option Symbol `AAPL 191004P00275000`, \\\n TW Future Symbol `/ESZ9`, or \\\n TW Future Option Symbol `./ESZ9 EW4U9 190927P2975`", "required": false, "schema": { "type": "string" }, "example": "AAPL" }, { "in": "query", "name": "instrument-type", "description": "The type of Instrument", "required": false, "schema": { "type": "string", "enum": [ "Bond", "Cryptocurrency", "Currency Pair", "Equity", "Equity Offering", "Equity Option", "Future", "Future Option", "Index", "Unknown", "Warrant" ] }, "example": "Bond" }, { "in": "query", "name": "include-closed-positions", "description": "If closed positions should be included in the query", "required": false, "schema": { "type": "boolean", "default": false }, "example": true }, { "in": "query", "name": "underlying-product-code", "description": "The underlying Future's Product code. i.e `ES`", "required": false, "schema": { "type": "string" }, "example": "ES" }, { "in": "query", "name": "partition-keys", "description": "Account partition keys (example: partition-keys[]={value1}&partition-keys[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } } }, { "in": "query", "name": "net-positions", "description": "Returns net positions grouped by instrument type and symbol", "required": false, "schema": { "type": "boolean", "default": false }, "example": true }, { "in": "query", "name": "include-marks", "description": "Include current quote mark (note: can decrease performance)", "required": false, "schema": { "type": "boolean", "default": false }, "example": true }, { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "A list of the account's positions, wrapped in a data.items array.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/CurrentPosition" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/positions" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed User-Agent header. Access tokens last 15 minutes; send Authorization: Bearer and a User-Agent like my-app/1.0 on every request.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account's authority level does not permit reading positions for this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Account not found. Verify the account_number and confirm you are hitting the correct environment (sandbox api.cert.tastyworks.com vs production api.tastyworks.com).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "positions" ], "operationId": "getAccountsAccountNumberPositions", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Account Positions" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /futures-option-chains/{symbol} — List Detailed Futures Option Chains Returns the full futures option chain for a given futures product code (e.g. `ES`) as a flat list of future option instruments. Each item is a complete future option representation. **Group:** Instruments · **operationId:** `getFuturesOptionChainsSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The futures option chain for the given product code as future option instruments. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No futures option chain exists for the given product code. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/futures-option-chains/{symbol}", "method": "get", "operation": { "description": "Returns the full futures option chain for a given futures product code (e.g. `ES`) as a flat list of future option instruments. Each item is a complete future option representation.", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "ES" } ], "responses": { "200": { "description": "The futures option chain for the given product code as future option instruments.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/FutureOption" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/futures-option-chains/{symbol}" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No futures option chain exists for the given product code.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "futures-option-chains" ], "operationId": "getFuturesOptionChainsSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Detailed Futures Option Chains" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /futures-option-chains/{symbol}/nested — List Nested Futures Option Chains Returns the futures option chain for a given futures product code (e.g. `ES`) in a nested form that groups data by expiration and strike to minimize redundant processing. Each strike provides its call and put symbols. **Group:** Instruments · **operationId:** `getFuturesOptionChainsSymbolNested` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The nested futures option chain for the given product code. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No futures option chain exists for the given product code. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/futures-option-chains/{symbol}/nested", "method": "get", "operation": { "description": "Returns the futures option chain for a given futures product code (e.g. `ES`) in a nested form that groups data by expiration and strike to minimize redundant processing. Each strike provides its call and put symbols.", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "ES" } ], "responses": { "200": { "description": "The nested futures option chain for the given product code.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/FuturesNestedOptionChainSerializer" }, "context": { "type": "string", "example": "/futures-option-chains/{symbol}/nested" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No futures option chain exists for the given product code.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "futures-option-chains" ], "operationId": "getFuturesOptionChainsSymbolNested", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Nested Futures Option Chains" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/cryptocurrencies — List Cryptocurrencies Returns active cryptocurrency instruments, optionally filtered by one or more symbols. Cryptocurrency symbols contain a forward slash (e.g. `BTC/USD`), so URL-encode them (e.g. `BTC%2FUSD`) before placing them in query parameters. **Group:** Instruments · **operationId:** `getInstrumentsCryptocurrencies` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (query) — Symbol(s) (example: symbol[]={value1}&symbol[]={value2}) ## Responses - `200` — Cryptocurrency instruments matching the requested symbols. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/cryptocurrencies", "method": "get", "operation": { "description": "Returns active cryptocurrency instruments, optionally filtered by one or more symbols. Cryptocurrency symbols contain a forward slash (e.g. `BTC/USD`), so URL-encode them (e.g. `BTC%2FUSD`) before placing them in query parameters.", "parameters": [ { "in": "query", "name": "symbol", "description": "Symbol(s) (example: symbol[]={value1}&symbol[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "BTC/USD" ] } ], "responses": { "200": { "description": "Cryptocurrency instruments matching the requested symbols.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Cryptocurrency" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/cryptocurrencies" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsCryptocurrencies", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Cryptocurrencies" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/cryptocurrencies/{symbol} — Get Cryptocurrency Returns a single cryptocurrency instrument for the given symbol. The symbol contains a forward slash (e.g. `BTC/USD`) and must be URL-encoded (e.g. `BTC%2FUSD`) in the path. **Group:** Instruments · **operationId:** `getInstrumentsCryptocurrenciesSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — Symbol ## Responses - `200` — The cryptocurrency instrument for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No cryptocurrency exists for the given symbol. Verify the symbol and that it is URL-encoded. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/cryptocurrencies/{symbol}", "method": "get", "operation": { "description": "Returns a single cryptocurrency instrument for the given symbol. The symbol contains a forward slash (e.g. `BTC/USD`) and must be URL-encoded (e.g. `BTC%2FUSD`) in the path.", "parameters": [ { "in": "path", "name": "symbol", "description": "Symbol", "required": true, "schema": { "type": "string" }, "example": "BTC/USD" } ], "responses": { "200": { "description": "The cryptocurrency instrument for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Cryptocurrency" }, "context": { "type": "string", "example": "/instruments/cryptocurrencies/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No cryptocurrency exists for the given symbol. Verify the symbol and that it is URL-encoded.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsCryptocurrenciesSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Cryptocurrency" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/equities — List Equities Returns equity definitions for one or more symbols. Optionally filter by lendability, or restrict results to index (`is-index`) or ETF (`is-etf`) instruments. **Group:** Instruments · **operationId:** `getInstrumentsEquities` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `page-offset` (query) — - `per-page` (query) — - `is-etf` (query) — Flag indicating if equity is an etf instrument - `is-index` (query) — Flag indicating if equity is an index instrument - `lendability` (query) — Lendability - `symbol` (query) — The symbol of the equity(s), i.e `AAPL` (example: symbol[]={value1}&symbol[]={value2}) ## Responses - `200` — Equity definitions matching the requested symbols and filters. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/equities", "method": "get", "operation": { "description": "Returns equity definitions for one or more symbols. Optionally filter by lendability, or restrict results to index (`is-index`) or ETF (`is-etf`) instruments.", "parameters": [ { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 1000, "default": 1000 }, "example": 10 }, { "in": "query", "name": "is-etf", "description": "Flag indicating if equity is an etf instrument", "required": false, "schema": { "type": "boolean" }, "example": true }, { "in": "query", "name": "is-index", "description": "Flag indicating if equity is an index instrument", "required": false, "schema": { "type": "boolean" }, "example": true }, { "in": "query", "name": "lendability", "description": "Lendability", "required": false, "schema": { "type": "string", "enum": [ "Easy To Borrow", "Locate Required", "Preborrow" ] }, "example": "Easy To Borrow" }, { "in": "query", "name": "symbol", "description": "The symbol of the equity(s), i.e `AAPL` (example: symbol[]={value1}&symbol[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "AAPL" ] } ], "responses": { "200": { "description": "Equity definitions matching the requested symbols and filters.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Equity" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/equities" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsEquities", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Equities" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/equities/{symbol} — Get Equity Returns a single equity definition for the provided symbol (e.g. `AAPL`). **Group:** Instruments · **operationId:** `getInstrumentsEquitiesSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — The symbol of the equity, i.e. `AAPL` ## Responses - `200` — The equity definition for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No equity exists for the given symbol. Verify the symbol is correct. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/equities/{symbol}", "method": "get", "operation": { "description": "Returns a single equity definition for the provided symbol (e.g. `AAPL`).", "parameters": [ { "in": "path", "name": "symbol", "description": "The symbol of the equity, i.e. `AAPL`", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "The equity definition for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Equity" }, "context": { "type": "string", "example": "/instruments/equities/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No equity exists for the given symbol. Verify the symbol is correct.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsEquitiesSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Equity" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/equities/active — List Active Equities Returns all active equities in a paginated fashion. Use `per-page` and `page-offset` to page through results, and optionally filter by lendability. **Group:** Instruments · **operationId:** `getInstrumentsEquitiesActive` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `page-offset` (query) — - `per-page` (query) — - `lendability` (query) — Lendability. i.e. `Easy To Borrow`, `Locate Required` or `Preborrow` ## Responses - `200` — A paginated list of active equities. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/equities/active", "method": "get", "operation": { "description": "Returns all active equities in a paginated fashion. Use `per-page` and `page-offset` to page through results, and optionally filter by lendability.", "parameters": [ { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 5000, "default": 1000 }, "example": 10 }, { "in": "query", "name": "lendability", "description": "Lendability. i.e. `Easy To Borrow`, `Locate Required` or `Preborrow`", "required": false, "schema": { "type": "string", "enum": [ "Easy To Borrow", "Locate Required", "Preborrow" ] }, "example": "Easy To Borrow" } ], "responses": { "200": { "description": "A paginated list of active equities.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Equity" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/equities/active" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsEquitiesActive", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Active Equities" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/equity-options/{symbol} — Get Equity Option Returns a single equity option instrument for the given symbol in OCC symbology (e.g. `SPY 230731C00393000`). Remember to URL-encode the embedded spaces. **Group:** Instruments · **operationId:** `getInstrumentsEquityOptionsSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — The symbol of the equity option using OCC Symbology, i.e. `FB 180629C00200000` - `active` (query) — Whether an option is available for trading with the broker. Terminology is somewhat misleading as this is generally used to filter non-standard / flex options out. ## Responses - `200` — The equity option instrument for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No equity option exists for the given symbol. Verify the OCC symbol and that spaces are URL-encoded. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/equity-options/{symbol}", "method": "get", "operation": { "description": "Returns a single equity option instrument for the given symbol in OCC symbology (e.g. `SPY 230731C00393000`). Remember to URL-encode the embedded spaces.", "parameters": [ { "in": "path", "name": "symbol", "description": "The symbol of the equity option using OCC Symbology, i.e. `FB 180629C00200000`", "required": true, "schema": { "type": "string" }, "example": "FB 180629C00200000" }, { "in": "query", "name": "active", "description": "Whether an option is available for trading with the broker.\n Terminology is somewhat misleading as this is generally used to filter non-standard / flex options out.", "required": false, "schema": { "type": "boolean" }, "example": true } ], "responses": { "200": { "description": "The equity option instrument for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/EquityOption" }, "context": { "type": "string", "example": "/instruments/equity-options/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No equity option exists for the given symbol. Verify the OCC symbol and that spaces are URL-encoded.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsEquityOptionsSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Equity Option" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-option-products — List Future Option Products Returns metadata for all supported future option products. A future option product is not a tradeable instrument; it describes the option contract code (root symbol) and expiration type, and includes the parent `future-product` it belongs to. **Group:** Instruments · **operationId:** `getInstrumentsFutureOptionProducts` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `page-offset` (query) — - `per-page` (query) — ## Responses - `200` — All supported future option products. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-option-products", "method": "get", "operation": { "description": "Returns metadata for all supported future option products. A future option product is not a tradeable instrument; it describes the option contract code (root symbol) and expiration type, and includes the parent `future-product` it belongs to.", "parameters": [ { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 1000, "default": 1000 }, "example": 10 } ], "responses": { "200": { "description": "All supported future option products.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/FutureOptionProduct" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/future-option-products" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureOptionProducts", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Future Option Products" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-option-products/{exchange}/{root_symbol} — Get Future Option Product Returns a single future option product identified by exchange and root symbol (e.g. exchange `CME`, root symbol `EW1`). **Group:** Instruments · **operationId:** `getInstrumentsFutureOptionProductsExchangeRootSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `exchange` (path, required) — - `root_symbol` (path, required) — ## Responses - `200` — The future option product for the given exchange and root symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No future option product exists for the given exchange and root symbol. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-option-products/{exchange}/{root_symbol}", "method": "get", "operation": { "description": "Returns a single future option product identified by exchange and root symbol (e.g. exchange `CME`, root symbol `EW1`).", "parameters": [ { "in": "path", "name": "exchange", "required": true, "schema": { "type": "string" } }, { "in": "path", "name": "root_symbol", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The future option product for the given exchange and root symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/FutureOptionProduct" }, "context": { "type": "string", "example": "/instruments/future-option-products/{exchange}/{root_symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No future option product exists for the given exchange and root symbol.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureOptionProductsExchangeRootSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Future Option Product" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-option-products/{root_symbol} — Get Future Option Product By Root Returns a single future option product identified by root symbol alone. Deprecated: prefer `/instruments/future-option-products/{exchange}/{root_symbol}`. **Group:** Instruments · **operationId:** `getInstrumentsFutureOptionProductsRootSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `root_symbol` (path, required) — ## Responses - `200` — The future option product for the given root symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No future option product exists for the given root symbol. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-option-products/{root_symbol}", "method": "get", "operation": { "description": "Returns a single future option product identified by root symbol alone. Deprecated: prefer `/instruments/future-option-products/{exchange}/{root_symbol}`.", "parameters": [ { "in": "path", "name": "root_symbol", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The future option product for the given root symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/FutureOptionProduct" }, "context": { "type": "string", "example": "/instruments/future-option-products/{root_symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No future option product exists for the given root symbol.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureOptionProductsRootSymbol", "deprecated": true, "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Future Option Product By Root" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-options/{symbol} — Get Future Option Returns a single future option for the given symbol using tastytrade symbology (e.g. `./ESZ9 EW4U9 190927P2975`). URL-encode the leading `./`, the forward slash, and the spaces before placing the symbol in the path. **Group:** Instruments · **operationId:** `getInstrumentsFutureOptionsSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — The symbol of the future option ## Responses - `200` — The future option for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No future option exists for the given symbol. Verify the symbol and that special characters are URL-encoded. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-options/{symbol}", "method": "get", "operation": { "description": "Returns a single future option for the given symbol using tastytrade symbology (e.g. `./ESZ9 EW4U9 190927P2975`). URL-encode the leading `./`, the forward slash, and the spaces before placing the symbol in the path.", "parameters": [ { "in": "path", "name": "symbol", "description": "The symbol of the future option", "required": true, "schema": { "type": "string" }, "example": "./ESZ9 EW4U9 190927P2975" } ], "responses": { "200": { "description": "The future option for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/FutureOption" }, "context": { "type": "string", "example": "/instruments/future-options/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No future option exists for the given symbol. Verify the symbol and that special characters are URL-encoded.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureOptionsSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Future Option" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-products — List Future Products Returns metadata for all supported futures products. A future product is not a tradeable instrument; it describes attributes such as the contract code and the months of the year that contracts are listed. For example, the E-mini S&P 500 product code is `ES` and every contract begins with `/ES`. **Group:** Instruments · **operationId:** `getInstrumentsFutureProducts` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `page-offset` (query) — - `per-page` (query) — ## Responses - `200` — All supported futures products. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-products", "method": "get", "operation": { "description": "Returns metadata for all supported futures products. A future product is not a tradeable instrument; it describes attributes such as the contract code and the months of the year that contracts are listed. For example, the E-mini S&P 500 product code is `ES` and every contract begins with `/ES`.", "parameters": [ { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 1000, "default": 1000 }, "example": 10 } ], "responses": { "200": { "description": "All supported futures products.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/FutureProduct" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/future-products" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureProducts", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Future Products" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/future-products/{exchange}/{code} — Get Future Product Returns a single future product identified by exchange and product code (e.g. exchange `CME`, code `CL`). **Group:** Instruments · **operationId:** `getInstrumentsFutureProductsExchangeCode` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `exchange` (path, required) — The exchange code - `code` (path, required) — The product code, i.e. `ES` ## Responses - `200` — The future product for the given exchange and product code. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No future product exists for the given exchange and product code. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/future-products/{exchange}/{code}", "method": "get", "operation": { "description": "Returns a single future product identified by exchange and product code (e.g. exchange `CME`, code `CL`).", "parameters": [ { "in": "path", "name": "exchange", "description": "The exchange code", "required": true, "schema": { "type": "string", "enum": [ "CBOED", "CFE", "CME", "SMALLS" ] }, "example": "CBOED" }, { "in": "path", "name": "code", "description": "The product code, i.e. `ES`", "required": true, "schema": { "type": "string" }, "example": "ES" } ], "responses": { "200": { "description": "The future product for the given exchange and product code.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/FutureProduct" }, "context": { "type": "string", "example": "/instruments/future-products/{exchange}/{code}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No future product exists for the given exchange and product code.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutureProductsExchangeCode", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Future Product" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/futures — List Futures Returns active outright futures contracts, optionally filtered by symbol or product code. Each future includes its associated product metadata nested under `future-product`. Futures symbols begin with a forward slash (e.g. `/ESU3`); URL-encode the slash (e.g. `%2FESU3`). **Group:** Instruments · **operationId:** `getInstrumentsFutures` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `page-offset` (query) — - `per-page` (query) — - `exchange` (query) — Name of the exchange for the product. Only used to avoid security id collisions if that is also given. - `only-active-futures` (query) — If true (defaults to true), only active futures are returned. - `product-code` (query) — The product code of the future(s), i.e. `product-code[]=ES&product-code[]=6A`. \ Ignored if `symbol` parameter is given. (example: product-code[]={value1}&product-code[]={value2}) - `security-id` (query) — Exchange-specific ID used for order routing (example: security-id[]={value1}&security-id[]={value2}) - `symbol` (query) — The symbol of the future(s), i.e. `symbol[]=ESZ9`. Leading forward slash is not required. (example: symbol[]={value1}&symbol[]={value2}) ## Responses - `200` — Outright futures matching the requested symbols, product codes, or security ids. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/futures", "method": "get", "operation": { "description": "Returns active outright futures contracts, optionally filtered by symbol or product code. Each future includes its associated product metadata nested under `future-product`. Futures symbols begin with a forward slash (e.g. `/ESU3`); URL-encode the slash (e.g. `%2FESU3`).", "parameters": [ { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 1000, "default": 1000 }, "example": 10 }, { "in": "query", "name": "exchange", "description": "Name of the exchange for the product. Only used to avoid security id collisions if that is also given.", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "only-active-futures", "description": "If true (defaults to true), only active futures are returned.", "required": false, "schema": { "type": "boolean" }, "example": true }, { "in": "query", "name": "product-code", "description": "The product code of the future(s), i.e. `product-code[]=ES&product-code[]=6A`. \\\n Ignored if `symbol` parameter is given. (example: product-code[]={value1}&product-code[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } } }, { "in": "query", "name": "security-id", "description": "Exchange-specific ID used for order routing (example: security-id[]={value1}&security-id[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } } }, { "in": "query", "name": "symbol", "description": "The symbol of the future(s), i.e. `symbol[]=ESZ9`. Leading forward slash is not required. (example: symbol[]={value1}&symbol[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "/ESU3" ] } ], "responses": { "200": { "description": "Outright futures matching the requested symbols, product codes, or security ids.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Future" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/futures" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFutures", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Futures" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/futures/{symbol} — Get Future Returns a single outright future for the given symbol (e.g. `/ESU3`). The leading forward slash is optional; URL-encode it (`%2F`) when present in the path. **Group:** Instruments · **operationId:** `getInstrumentsFuturesSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — The symbol of the future, i.e. `ESZ9`. Leading forward slash is not required. ## Responses - `200` — The outright future for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No future exists for the given symbol. Verify the symbol and that the forward slash is URL-encoded. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/futures/{symbol}", "method": "get", "operation": { "description": "Returns a single outright future for the given symbol (e.g. `/ESU3`). The leading forward slash is optional; URL-encode it (`%2F`) when present in the path.", "parameters": [ { "in": "path", "name": "symbol", "description": "The symbol of the future, i.e. `ESZ9`. Leading forward slash is not required.", "required": true, "schema": { "type": "string" }, "example": "ESZ9" } ], "responses": { "200": { "description": "The outright future for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Future" }, "context": { "type": "string", "example": "/instruments/futures/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No future exists for the given symbol. Verify the symbol and that the forward slash is URL-encoded.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsFuturesSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Future" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/quantity-decimal-precisions — List Quantity Decimal Precisions Returns the quantity decimal precision for each instrument type or symbol. The `value` defines how many decimal places a quantity may use; for example BTC/USD has a precision of 8, so `0.12345678` is valid but `0.123456789` is not. A value of 0 means the instrument must trade in whole numbers. **Group:** Instruments · **operationId:** `getInstrumentsQuantityDecimalPrecisions` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `200` — Quantity decimal precision definitions. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/quantity-decimal-precisions", "method": "get", "operation": { "description": "Returns the quantity decimal precision for each instrument type or symbol. The `value` defines how many decimal places a quantity may use; for example BTC/USD has a precision of 8, so `0.12345678` is valid but `0.123456789` is not. A value of 0 means the instrument must trade in whole numbers.", "responses": { "200": { "description": "Quantity decimal precision definitions.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/QuantityDecimalPrecision" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/quantity-decimal-precisions" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsQuantityDecimalPrecisions", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Quantity Decimal Precisions" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/search — getInstrumentsSearch Search instruments by symbol, description, or tags **Group:** Instruments · **operationId:** `getInstrumentsSearch` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `category` (query) — Comma-separated categories to filter (case-insensitive) - `exchange` (query) — Comma-separated exchanges to filter (case-insensitive) - `from-date` (query) — Lower bound on stops_trading_at; surfaces expired events that stopped trading on/after this date - `instrument-sub-type` (query) — Comma-separated instrument sub-types to filter (equities only): ETF, Index - `limit` (query) — Maximum number of results - `query` (query) — Search query - `type` (query) — Comma-separated instrument types to filter ## Responses - `200` — Search instruments by symbol, description, or tags # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/search", "method": "get", "operation": { "description": "Search instruments by symbol, description, or tags", "parameters": [ { "in": "query", "name": "category", "description": "Comma-separated categories to filter (case-insensitive)", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "exchange", "description": "Comma-separated exchanges to filter (case-insensitive)", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "from-date", "description": "Lower bound on stops_trading_at; surfaces expired events that stopped trading on/after this date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "instrument-sub-type", "description": "Comma-separated instrument sub-types to filter (equities only): ETF, Index", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "limit", "description": "Maximum number of results", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 100, "default": 25 }, "example": 1 }, { "in": "query", "name": "query", "description": "Search query", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "type", "description": "Comma-separated instrument types to filter", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Search instruments by symbol, description, or tags", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/SearchableInstrumentDeserializer" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/search" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsSearch", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/warrants — List Warrants Returns warrant definitions, optionally filtered by one or more symbols (e.g. `NKLAW`). Without `symbol`, only active warrants are returned. With `symbol`, the warrants matching the given symbol(s) are returned whether or not they are active, so check the `active` field on each item. A symbol that matches no warrant is not an error: the response is 200 with an empty `items` array. Use `GET /instruments/warrants/{symbol}` if you need a 404 for an unknown symbol. The endpoint does not paginate. **Group:** Instruments · **operationId:** `getInstrumentsWarrants` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (query) — The symbol of the warrant(s), i.e `NKLAW` (example: symbol[]={value1}&symbol[]={value2}) ## Responses - `200` — Warrant definitions: the active warrants when no `symbol` is given, otherwise those matching the requested symbols (active or not). `items` is empty when nothing matches. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/warrants", "method": "get", "operation": { "description": "Returns warrant definitions, optionally filtered by one or more symbols (e.g. `NKLAW`). Without `symbol`, only active warrants are returned. With `symbol`, the warrants matching the given symbol(s) are returned whether or not they are active, so check the `active` field on each item. A symbol that matches no warrant is not an error: the response is 200 with an empty `items` array. Use `GET /instruments/warrants/{symbol}` if you need a 404 for an unknown symbol. The endpoint does not paginate.", "parameters": [ { "in": "query", "name": "symbol", "description": "The symbol of the warrant(s), i.e `NKLAW` (example: symbol[]={value1}&symbol[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "NKLAW" ] } ], "responses": { "200": { "description": "Warrant definitions: the active warrants when no `symbol` is given, otherwise those matching the requested symbols (active or not). `items` is empty when nothing matches.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Warrant" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/instruments/warrants" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsWarrants", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Warrants" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /instruments/warrants/{symbol} — Get Warrant Returns a single warrant definition for the provided symbol (e.g. `SEPAW`). **Group:** Instruments · **operationId:** `getInstrumentsWarrantsSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The warrant definition for the requested symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No warrant exists for the given symbol. The error code is `record_not_found`. Verify the symbol is correct. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/instruments/warrants/{symbol}", "method": "get", "operation": { "description": "Returns a single warrant definition for the provided symbol (e.g. `SEPAW`).", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "The warrant definition for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Warrant" }, "context": { "type": "string", "example": "/instruments/warrants/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No warrant exists for the given symbol. The error code is `record_not_found`. Verify the symbol is correct.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "instruments" ], "operationId": "getInstrumentsWarrantsSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Warrant" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /option-chains/{symbol} — List Detailed Option Chains Returns the full equity option chain for an underlying symbol (e.g. `AAPL`) as a flat list of equity option instruments. Each item is a complete equity option representation. **Group:** Instruments · **operationId:** `getOptionChainsSymbol` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The equity option chain for the given underlying symbol as equity option instruments. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No option chain exists for the given underlying symbol. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/option-chains/{symbol}", "method": "get", "operation": { "description": "Returns the full equity option chain for an underlying symbol (e.g. `AAPL`) as a flat list of equity option instruments. Each item is a complete equity option representation.", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "The equity option chain for the given underlying symbol as equity option instruments.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/EquityOption" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/option-chains/{symbol}" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No option chain exists for the given underlying symbol.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "option-chains" ], "operationId": "getOptionChainsSymbol", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Detailed Option Chains" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /option-chains/{symbol}/compact — List Compact Option Chains Returns the equity option chain for an underlying symbol (e.g. `AAPL`) in a compact form that concatenates every strike symbol across all expirations into a single array, minimizing content size. **Group:** Instruments · **operationId:** `getOptionChainsSymbolCompact` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The compact equity option chain for the given underlying symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No option chain exists for the given underlying symbol. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/option-chains/{symbol}/compact", "method": "get", "operation": { "description": "Returns the equity option chain for an underlying symbol (e.g. `AAPL`) in a compact form that concatenates every strike symbol across all expirations into a single array, minimizing content size.", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "The compact equity option chain for the given underlying symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CompactOptionChainList" }, "context": { "type": "string", "example": "/option-chains/{symbol}/compact" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No option chain exists for the given underlying symbol.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "option-chains" ], "operationId": "getOptionChainsSymbolCompact", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Compact Option Chains" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /option-chains/{symbol}/nested — List Nested Option Chains Returns the equity option chain for an underlying symbol (e.g. `AAPL`) in a nested form that groups expirations and strikes together to minimize redundant processing. Each strike provides its call and put symbols. **Group:** Instruments · **operationId:** `getOptionChainsSymbolNested` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `symbol` (path, required) — ## Responses - `200` — The nested equity option chain for the given underlying symbol. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No option chain exists for the given underlying symbol. - `429` — Request rate exceeded. Back off exponentially and reduce request frequency. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/option-chains/{symbol}/nested", "method": "get", "operation": { "description": "Returns the equity option chain for an underlying symbol (e.g. `AAPL`) in a nested form that groups expirations and strikes together to minimize redundant processing. Each strike provides its call and put symbols.", "parameters": [ { "in": "path", "name": "symbol", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "The nested equity option chain for the given underlying symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NestedOptionChainList" }, "context": { "type": "string", "example": "/option-chains/{symbol}/nested" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No option chain exists for the given underlying symbol.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce request frequency.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "option-chains" ], "operationId": "getOptionChainsSymbolNested", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Nested Option Chains" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /margin/accounts/{account_number}/dry-run — Margin Requirements Dry Run Estimates the margin impact of a prospective order on the account without placing it. The body matches the order you would submit, plus account-number, underlying-symbol, and underlying-instrument-type (Equity, Equity Option, Future, Future Option, or Cryptocurrency). The response compares the account before and after via change-in-margin-requirement, change-in-buying-power, and the current-buying-power vs new-buying-power pair, with full per-underlying breakdowns under last-results, base-results, and new-order-results. A dry-run never creates an order, so it is safe to repeat; always run it before submitting a real order. **Group:** Margin Requirements · **operationId:** `createMarginAccountsAccountNumberDryRun` ## Parameters - `account_number` (path, required) — ## Responses - `200` — The estimated margin impact of the order, comparing the account before and after, with per-underlying breakdowns. - `401` — Authentication failed. The Authorization bearer token is missing, expired (access tokens last 15 minutes), or the required User-Agent header is missing or malformed. - `403` — Forbidden. The token is valid but its scope or the account's authority level does not permit running a margin dry-run on this account. - `404` — No account was found for the supplied account_number, or the wrong environment was used (sandbox vs production). - `422` — The order could not be evaluated. The body is missing required fields, uses non-dasherized or wrong-typed keys, or describes an order that is invalid in context (for example an unknown symbol). Read error.message for the specific reason. - `429` — Rate limit exceeded. Back off exponentially and reduce the request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/margin/accounts/{account_number}/dry-run", "method": "post", "operation": { "description": "Estimates the margin impact of a prospective order on the account without placing it. The body matches the order you would submit, plus account-number, underlying-symbol, and underlying-instrument-type (Equity, Equity Option, Future, Future Option, or Cryptocurrency). The response compares the account before and after via change-in-margin-requirement, change-in-buying-power, and the current-buying-power vs new-buying-power pair, with full per-underlying breakdowns under last-results, base-results, and new-order-results. A dry-run never creates an order, so it is safe to repeat; always run it before submitting a real order.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "required": [ "order-type", "time-in-force", "account-number", "underlying-symbol", "underlying-instrument-type" ], "properties": { "account-number": { "type": "string" }, "underlying-symbol": { "type": "string" }, "order-type": { "type": "string" }, "time-in-force": { "type": "string" }, "gtc-date": { "type": "string", "format": "date" }, "price": { "type": "string", "format": "numeric" }, "price-effect": { "type": "string", "enum": [ "Credit", "Debit" ] }, "stop-trigger": { "type": "string", "format": "numeric" }, "replaces-order-id": { "type": "string", "format": "numeric" }, "legs": { "type": "array", "minItems": 1, "maxItems": 4, "uniqueItems": true, "items": { "type": "object", "required": [ "symbol", "instrument-type", "action" ], "properties": { "symbol": { "type": "string" }, "instrument-type": { "type": "string" }, "quantity": { "type": "string", "format": "numeric" }, "action": { "type": "string" }, "remaining-quantity": { "type": "string", "format": "numeric" } } } }, "underlying-instrument-type": { "type": "string", "description": "The instrument type of the underlying symbol.", "enum": [ "Equity", "Equity Option", "Future", "Future Option", "Cryptocurrency" ], "example": "Equity" } } } } }, "description": "the order to evaluate for margin requirements" }, "responses": { "200": { "description": "The estimated margin impact of the order, comparing the account before and after, with per-underlying breakdowns.", "content": { "application/json": {} } }, "401": { "description": "Authentication failed. The Authorization bearer token is missing, expired (access tokens last 15 minutes), or the required User-Agent header is missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden. The token is valid but its scope or the account's authority level does not permit running a margin dry-run on this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account was found for the supplied account_number, or the wrong environment was used (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The order could not be evaluated. The body is missing required fields, uses non-dasherized or wrong-typed keys, or describes an order that is invalid in context (for example an unknown symbol). Read error.message for the specific reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially and reduce the request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "margin-requirements" ], "operationId": "createMarginAccountsAccountNumberDryRun", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Margin Requirements Dry Run" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /margin/accounts/{account_number}/requirements — Get Account Margin Requirements Returns the account's current margin and capital requirements report, grouped by underlying symbol. The top level summarizes the whole account (margin-requirement, maintenance-requirement, margin-equity, maintenance-excess, and buying-power figures, including separate reg-t-* values), while each entry under groups breaks down one underlying with its own requirement totals, position-entries, and price-increase-percent / price-decrease-percent values. Read this to understand how much of the account is committed to margin before placing new orders. **Group:** Margin Requirements · **operationId:** `getMarginAccountsAccountNumberRequirements` ## Parameters - `account_number` (path, required) — ## Responses - `200` — The account's current margin/capital requirements report, grouped by underlying symbol. - `401` — Authentication failed. The Authorization bearer token is missing, expired (access tokens last 15 minutes), or the required User-Agent header is missing or malformed. - `403` — Forbidden. The token is valid but its scope or the account's authority level does not permit reading this account's margin requirements. - `404` — No account was found for the supplied account_number, or the wrong environment was used (sandbox vs production). - `429` — Rate limit exceeded. Back off exponentially and reduce the request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/margin/accounts/{account_number}/requirements", "method": "get", "operation": { "description": "Returns the account's current margin and capital requirements report, grouped by underlying symbol. The top level summarizes the whole account (margin-requirement, maintenance-requirement, margin-equity, maintenance-excess, and buying-power figures, including separate reg-t-* values), while each entry under groups breaks down one underlying with its own requirement totals, position-entries, and price-increase-percent / price-decrease-percent values. Read this to understand how much of the account is committed to margin before placing new orders.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "The account's current margin/capital requirements report, grouped by underlying symbol.", "content": { "application/json": {} } }, "401": { "description": "Authentication failed. The Authorization bearer token is missing, expired (access tokens last 15 minutes), or the required User-Agent header is missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden. The token is valid but its scope or the account's authority level does not permit reading this account's margin requirements.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account was found for the supplied account_number, or the wrong environment was used (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially and reduce the request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "margin-requirements" ], "operationId": "getMarginAccountsAccountNumberRequirements", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account Margin Requirements" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-data/by-type — Get Quotes By Instrument Type Fetches real-time REST quotes for multiple securities at once. Pass each instrument type as a query parameter (`equity`, `equity-option`, `index`, `future`, `future-option`, `cryptocurrency`) whose value is a comma-delimited list of symbols in tastytrade symbology. The combined number of symbols across all type parameters is capped at 100 per request; split larger sets across multiple calls or use the DXLink streaming feed instead. Available to funded account holders only; no delayed quotes are served over REST. For continuous, low-latency updates prefer streaming over polling. **Group:** Market Data · **operationId:** `getMarketDataByType` ## Parameters - `index` (query) — Comma-separated list of index symbols. - `equity` (query) — Comma-separated list of equity symbols. - `equity-option` (query) — Comma-separated list of equity option symbols in OCC symbology. - `future` (query) — Comma-separated list of future symbols. - `future-option` (query) — Comma-separated list of future option symbols. - `cryptocurrency` (query) — Comma-separated list of cryptocurrency symbols. ## Responses - `200` — Quotes for the requested symbols, returned as a list of quote objects under `data.items`. JSON keys are dasherized and numeric prices are returned as decimal strings. - `400` — Bad request. A symbol or instrument-type query parameter was malformed or could not be parsed. Verify the type parameter keys and that symbols follow tastytrade symbology. - `401` — Unauthorized. The access token is missing, expired (tokens last 15 minutes), or the required `User-Agent: /` header was missing or malformed. - `403` — Forbidden. The account or token is not permitted to access this resource. - `429` — Too many requests. Reduce request frequency before retrying. For continuous updates, prefer streaming market data over polling. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-data/by-type", "method": "get", "operation": { "tags": [ "market-data-controller" ], "summary": "Get Quotes By Instrument Type", "operationId": "getMarketDataByType", "parameters": [ { "name": "index", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of index symbols.", "example": [ "SPX" ] }, { "name": "equity", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of equity symbols.", "example": [ "AAPL", "TSLA" ] }, { "name": "equity-option", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of equity option symbols in OCC symbology.", "example": [ "SPY 250428P00355000" ] }, { "name": "future", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of future symbols.", "example": [ "/CLM5" ] }, { "name": "future-option", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of future option symbols.", "example": [ "/MESU5EX3M5 250620C6450" ] }, { "name": "cryptocurrency", "in": "query", "required": false, "schema": { "type": "array", "items": { "type": "string" }, "default": [] }, "style": "form", "explode": false, "description": "Comma-separated list of cryptocurrency symbols.", "example": [ "BTC/USD" ] } ], "responses": { "200": { "description": "Quotes for the requested symbols, returned as a list of quote objects under `data.items`. JSON keys are dasherized and numeric prices are returned as decimal strings.", "content": { "*/*": { "schema": { "$ref": "#/components/schemas/MarketData" } }, "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/MarketData" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-data/by-type" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "400": { "description": "Bad request. A symbol or instrument-type query parameter was malformed or could not be parsed. Verify the type parameter keys and that symbols follow tastytrade symbology.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "401": { "description": "Unauthorized. The access token is missing, expired (tokens last 15 minutes), or the required `User-Agent: /` header was missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden. The account or token is not permitted to access this resource.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "429": { "description": "Too many requests. Reduce request frequency before retrying. For continuous updates, prefer streaming market data over polling.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "description": "Fetches real-time REST quotes for multiple securities at once. Pass each instrument type as a query parameter (`equity`, `equity-option`, `index`, `future`, `future-option`, `cryptocurrency`) whose value is a comma-delimited list of symbols in tastytrade symbology. The combined number of symbols across all type parameters is capped at 100 per request; split larger sets across multiple calls or use the DXLink streaming feed instead. Available to funded account holders only; no delayed quotes are served over REST. For continuous, low-latency updates prefer streaming over polling." } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-metrics — Get Market Metrics By Symbols Returns volatility and liquidity metrics for one or more underlyings in a single read-only request. Pass a comma-separated `symbols` query list (e.g. `?symbols=AAPL,FB,BRK%2FB`); each underlying is returned as a `MarketMetricInfo` object including IV index, IV rank/percentile, liquidity ratings, and per-expiration option implied volatilities. This is a snapshot endpoint. **Group:** Market Metrics · **operationId:** `getMarketMetricsIndex` ## Parameters - `symbols` (query, required) — Comma separated list of symbols i.e. ?symbols=AAPL,FB,BRK%2FB ## Responses - `200` — An array of volatility and liquidity metrics, one entry per requested symbol. - `401` — Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`. - `403` — Authenticated, but not authorized to access this resource. - `422` — Unprocessable content — the request was invalid for this endpoint; the reason is returned in `error.message`. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially and retry. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-metrics", "method": "get", "operation": { "description": "Returns volatility and liquidity metrics for one or more underlyings in a single read-only request. Pass a comma-separated `symbols` query list (e.g. `?symbols=AAPL,FB,BRK%2FB`); each underlying is returned as a `MarketMetricInfo` object including IV index, IV rank/percentile, liquidity ratings, and per-expiration option implied volatilities. This is a snapshot endpoint.", "parameters": [ { "in": "query", "name": "symbols", "description": "Comma separated list of symbols i.e. ?symbols=AAPL,FB,BRK%2FB", "required": true, "schema": { "type": "string" }, "example": "AAPL,FB,BRK/B" } ], "responses": { "200": { "description": "An array of volatility and liquidity metrics, one entry per requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/MarketMetricInfo" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-metrics" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but not authorized to access this resource.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "422": { "description": "Unprocessable content — the request was invalid for this endpoint; the reason is returned in `error.message`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially and retry.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "operationId": "getMarketMetricsIndex", "tags": [ "market-metrics" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Market Metrics By Symbols" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-metrics/historic-corporate-events/dividends/{symbol} — Get Historical Dividends Returns the historical dividend schedule for a single underlying identified by the `symbol` path parameter. Each entry reports the date the dividend occurred and the per-share amount, useful for reconciling payouts or estimating yield. **Group:** Market Metrics · **operationId:** `getMarketMetricsDividendsSymbol` ## Parameters - `symbol` (path, required) — Symbol to get dividends data for ## Responses - `200` — An array of historical dividend records for the requested symbol. - `401` — Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`. - `403` — Authenticated, but not authorized to access this resource. - `404` — The requested resource was not found. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially and retry. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-metrics/historic-corporate-events/dividends/{symbol}", "method": "get", "operation": { "description": "Returns the historical dividend schedule for a single underlying identified by the `symbol` path parameter. Each entry reports the date the dividend occurred and the per-share amount, useful for reconciling payouts or estimating yield.", "parameters": [ { "in": "path", "name": "symbol", "description": "Symbol to get dividends data for", "required": true, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "An array of historical dividend records for the requested symbol.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/DividendInfo" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-metrics/historic-corporate-events/dividends/{symbol}" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but not authorized to access this resource.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The requested resource was not found.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially and retry.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "operationId": "getMarketMetricsDividendsSymbol", "tags": [ "market-metrics" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Historical Dividends" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-metrics/historic-corporate-events/earnings-reports/{symbol} — Get Historical Earnings Reports Returns historical earnings announcements for a single underlying identified by the `symbol` path parameter. Use the required `start-date` query parameter to bound the window from that date until now, and the optional `end-date` to cap the upper bound. Each entry reports the announcement date and reported earnings per share. **Group:** Market Metrics · **operationId:** `getMarketMetricsEarningsSymbol` ## Parameters - `symbol` (path, required) — Symbol to get earnings data for - `start-date` (query, required) — Limits earnings data from start-date until now - `end-date` (query) — Limits earnings data from start-date until end-date ## Responses - `200` — An array of historical earnings records for the requested symbol within the requested date window. - `401` — Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`. - `403` — Authenticated, but not authorized to access this resource. - `404` — The requested resource was not found. - `422` — Unprocessable content — the request was invalid for this endpoint. Dates must be ISO-8601 (`YYYY-MM-DD`); the reason is returned in `error.message`. - `429` — Request rate exceeded reasonable thresholds. Back off exponentially and retry. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-metrics/historic-corporate-events/earnings-reports/{symbol}", "method": "get", "operation": { "description": "Returns historical earnings announcements for a single underlying identified by the `symbol` path parameter. Use the required `start-date` query parameter to bound the window from that date until now, and the optional `end-date` to cap the upper bound. Each entry reports the announcement date and reported earnings per share.", "parameters": [ { "in": "path", "name": "symbol", "description": "Symbol to get earnings data for", "required": true, "schema": { "type": "string" }, "example": "AAPL" }, { "in": "query", "name": "start-date", "description": "Limits earnings data from start-date until now", "required": true, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "end-date", "description": "Limits earnings data from start-date until end-date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "An array of historical earnings records for the requested symbol within the requested date window.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/EarningsInfo" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-metrics/historic-corporate-events/earnings-reports/{symbol}" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid `Authorization` bearer token (tokens expire after 15 minutes), or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but not authorized to access this resource.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The requested resource was not found.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "Unprocessable content — the request was invalid for this endpoint. Dates must be ISO-8601 (`YYYY-MM-DD`); the reason is returned in `error.message`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially and retry.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "operationId": "getMarketMetricsEarningsSymbol", "tags": [ "market-metrics" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Historical Earnings Reports" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/equities/holidays — Get Equity Market Holidays Returns the equity market calendar, listing full-day market holidays and early-close half days. Use it to skip non-trading dates and to flag shortened sessions in your scheduling logic. **Group:** Market Sessions · **operationId:** `getMarketTimeEquitiesHolidays` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `200` — The equity market calendar of holidays and half days. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/equities/holidays", "method": "get", "operation": { "description": "Returns the equity market calendar, listing full-day market holidays and early-close half days. Use it to skip non-trading dates and to flag shortened sessions in your scheduling logic.", "responses": { "200": { "description": "The equity market calendar of holidays and half days.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/MarketCalendarDeserializer" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-time/equities/holidays" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeEquitiesHolidays", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Equity Market Holidays" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/equities/sessions/current — Get Current Equities Session Returns the current equities trading session along with its previous and next sessions. Optionally pass `current-time` to evaluate the session as of a specific instant instead of now; the response `state` field indicates the market's current state. **Group:** Market Sessions · **operationId:** `getMarketTimeEquitiesSessionsCurrent` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `current-time` (query) — The time the current session is based on ## Responses - `200` — The current equities session with its surrounding previous and next sessions. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `422` — The `current-time` value is not a valid ISO-8601 date-time. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/equities/sessions/current", "method": "get", "operation": { "description": "Returns the current equities trading session along with its previous and next sessions. Optionally pass `current-time` to evaluate the session as of a specific instant instead of now; the response `state` field indicates the market's current state.", "parameters": [ { "in": "query", "name": "current-time", "description": "The time the current session is based on", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" } ], "responses": { "200": { "description": "The current equities session with its surrounding previous and next sessions.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CurrentSession" }, "context": { "type": "string", "example": "/market-time/equities/sessions/current" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "The `current-time` value is not a valid ISO-8601 date-time.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeEquitiesSessionsCurrent", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Current Equities Session" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/equities/sessions/next — Get Next Equities Session Returns the next equities trading session. Optionally pass `date` to find the first session on or after that date instead of after today. **Group:** Market Sessions · **operationId:** `getMarketTimeEquitiesSessionsNext` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `date` (query) — Find session on or after this date ## Responses - `200` — The next equities session timings. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `422` — The `date` value is not a valid ISO-8601 date. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/equities/sessions/next", "method": "get", "operation": { "description": "Returns the next equities trading session. Optionally pass `date` to find the first session on or after that date instead of after today.", "parameters": [ { "in": "query", "name": "date", "description": "Find session on or after this date", "required": false, "schema": { "type": "string", "format": "date", "default": "2026-10-26" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "The next equities session timings.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NextSession" }, "context": { "type": "string", "example": "/market-time/equities/sessions/next" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "The `date` value is not a valid ISO-8601 date.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeEquitiesSessionsNext", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Next Equities Session" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/equities/sessions/previous — Get Previous Equities Session Returns the previous equities trading session. Optionally pass `date` to find the most recent session before that date instead of before today. **Group:** Market Sessions · **operationId:** `getMarketTimeEquitiesSessionsPrevious` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `date` (query) — Find session before this date ## Responses - `200` — The previous equities session timings. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `422` — The `date` value is not a valid ISO-8601 date. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/equities/sessions/previous", "method": "get", "operation": { "description": "Returns the previous equities trading session. Optionally pass `date` to find the most recent session before that date instead of before today.", "parameters": [ { "in": "query", "name": "date", "description": "Find session before this date", "required": false, "schema": { "type": "string", "format": "date", "default": "2026-10-26" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "The previous equities session timings.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PreviousSession" }, "context": { "type": "string", "example": "/market-time/equities/sessions/previous" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "The `date` value is not a valid ISO-8601 date.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeEquitiesSessionsPrevious", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Previous Equities Session" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/futures/holidays/{instrument_collection} — Get Futures Market Holidays By Exchange Returns the futures market calendar for a single exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter, listing full-day market holidays and early-close half days for that exchange. **Group:** Market Sessions · **operationId:** `getMarketTimeFuturesHolidaysInstrumentCollection` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `instrument_collection` (path, required) — Futures exchange, one of: CFE, CME ## Responses - `200` — The futures market calendar of holidays and half days for the requested exchange. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No calendar found for the supplied `instrument_collection`. - `422` — The `instrument_collection` path value is not a supported futures exchange (`CFE` or `CME`). - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/futures/holidays/{instrument_collection}", "method": "get", "operation": { "description": "Returns the futures market calendar for a single exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter, listing full-day market holidays and early-close half days for that exchange.", "parameters": [ { "in": "path", "name": "instrument_collection", "description": "Futures exchange, one of: CFE, CME", "required": true, "schema": { "type": "string", "enum": [ "CFE", "CME" ] }, "example": "CFE" } ], "responses": { "200": { "description": "The futures market calendar of holidays and half days for the requested exchange.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/MarketCalendarDeserializer" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-time/futures/holidays/{instrument_collection}" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No calendar found for the supplied `instrument_collection`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The `instrument_collection` path value is not a supported futures exchange (`CFE` or `CME`).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeFuturesHolidaysInstrumentCollection", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Futures Market Holidays By Exchange" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/futures/sessions/current — Get Current Futures Sessions Returns the current trading session for each supported futures exchange (`CFE` and `CME`), each with its previous and next sessions. Use this to see the current session state across all futures collections in a single call. **Group:** Market Sessions · **operationId:** `getMarketTimeFuturesSessionsCurrent` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `200` — An array of current futures sessions, one per supported exchange. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/futures/sessions/current", "method": "get", "operation": { "description": "Returns the current trading session for each supported futures exchange (`CFE` and `CME`), each with its previous and next sessions. Use this to see the current session state across all futures collections in a single call.", "responses": { "200": { "description": "An array of current futures sessions, one per supported exchange.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/CurrentSession" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-time/futures/sessions/current" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeFuturesSessionsCurrent", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Current Futures Sessions" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/futures/sessions/current/{instrument_collection} — Get Current Futures Session By Exchange Returns the current trading session for a single futures exchange identified by the `instrument_collection` path parameter (`CFE` or `CME`), including its previous and next sessions and current session state. **Group:** Market Sessions · **operationId:** `getMarketTimeFuturesSessionsCurrentInstrumentCollection` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `instrument_collection` (path, required) — Futures exchange, one of: CFE, CME ## Responses - `200` — The current futures session for the requested exchange. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No session found for the supplied `instrument_collection`. - `422` — The `instrument_collection` path value is not a supported futures exchange (`CFE` or `CME`). - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/futures/sessions/current/{instrument_collection}", "method": "get", "operation": { "description": "Returns the current trading session for a single futures exchange identified by the `instrument_collection` path parameter (`CFE` or `CME`), including its previous and next sessions and current session state.", "parameters": [ { "in": "path", "name": "instrument_collection", "description": "Futures exchange, one of: CFE, CME", "required": true, "schema": { "type": "string", "enum": [ "CFE", "CME" ] }, "example": "CFE" } ], "responses": { "200": { "description": "The current futures session for the requested exchange.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CurrentSession" }, "context": { "type": "string", "example": "/market-time/futures/sessions/current/{instrument_collection}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No session found for the supplied `instrument_collection`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The `instrument_collection` path value is not a supported futures exchange (`CFE` or `CME`).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeFuturesSessionsCurrentInstrumentCollection", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Current Futures Session By Exchange" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/futures/sessions/next/{instrument_collection} — Get Next Futures Session By Exchange Returns the next trading session for a single futures exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter. Optionally pass `date` to find the first session on or after that date. **Group:** Market Sessions · **operationId:** `getMarketTimeFuturesSessionsNextInstrumentCollection` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `instrument_collection` (path, required) — Futures exchange, one of: CFE, CME - `date` (query) — Find session on or after this date ## Responses - `200` — The next futures session for the requested exchange. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No session found for the supplied `instrument_collection`. - `422` — The `instrument_collection` is not a supported futures exchange, or `date` is not a valid ISO-8601 date. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/futures/sessions/next/{instrument_collection}", "method": "get", "operation": { "description": "Returns the next trading session for a single futures exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter. Optionally pass `date` to find the first session on or after that date.", "parameters": [ { "in": "path", "name": "instrument_collection", "description": "Futures exchange, one of: CFE, CME", "required": true, "schema": { "type": "string", "enum": [ "CFE", "CME" ] }, "example": "CFE" }, { "in": "query", "name": "date", "description": "Find session on or after this date", "required": false, "schema": { "type": "string", "format": "date", "default": "2026-10-26" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "The next futures session for the requested exchange.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NextSession" }, "context": { "type": "string", "example": "/market-time/futures/sessions/next/{instrument_collection}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No session found for the supplied `instrument_collection`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The `instrument_collection` is not a supported futures exchange, or `date` is not a valid ISO-8601 date.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeFuturesSessionsNextInstrumentCollection", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Next Futures Session By Exchange" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/futures/sessions/previous/{instrument_collection} — Get Previous Futures Session By Exchange Returns the previous trading session for a single futures exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter. Optionally pass `date` to find the most recent session before that date. **Group:** Market Sessions · **operationId:** `getMarketTimeFuturesSessionsPreviousInstrumentCollection` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `instrument_collection` (path, required) — Futures exchange, one of: CFE, CME - `date` (query) — Find session before this date ## Responses - `200` — The previous futures session for the requested exchange. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `404` — No session found for the supplied `instrument_collection`. - `422` — The `instrument_collection` is not a supported futures exchange, or `date` is not a valid ISO-8601 date. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/futures/sessions/previous/{instrument_collection}", "method": "get", "operation": { "description": "Returns the previous trading session for a single futures exchange (`CFE` or `CME`) given by the `instrument_collection` path parameter. Optionally pass `date` to find the most recent session before that date.", "parameters": [ { "in": "path", "name": "instrument_collection", "description": "Futures exchange, one of: CFE, CME", "required": true, "schema": { "type": "string", "enum": [ "CFE", "CME" ] }, "example": "CFE" }, { "in": "query", "name": "date", "description": "Find session before this date", "required": false, "schema": { "type": "string", "format": "date", "default": "2026-10-26" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "The previous futures session for the requested exchange.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PreviousSession" }, "context": { "type": "string", "example": "/market-time/futures/sessions/previous/{instrument_collection}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No session found for the supplied `instrument_collection`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The `instrument_collection` is not a supported futures exchange, or `date` is not a valid ISO-8601 date.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeFuturesSessionsPreviousInstrumentCollection", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Previous Futures Session By Exchange" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/sessions — List Sessions For Date Range Returns the timings for each trading session in a date range for a single instrument collection. Pass `from-date`, `to-date`, and optionally `instrument-collection` (defaults to `Equity`); the span between `from-date` and `to-date` must not exceed 9 months. Useful for building a calendar of market hours. **Group:** Market Sessions · **operationId:** `getMarketTimeSessions` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `from-date` (query) — The date to start from - `instrument-collection` (query) — The instrument collection to get sessions for - `to-date` (query, required) — The date to end at, the difference between from and to date must not exceed 9 months ## Responses - `200` — An array of session timings, one per trading day in the requested range. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `422` — Invalid query parameters, for example a missing `to-date` or a `from-date`/`to-date` span that exceeds the 9-month maximum. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/sessions", "method": "get", "operation": { "description": "Returns the timings for each trading session in a date range for a single instrument collection. Pass `from-date`, `to-date`, and optionally `instrument-collection` (defaults to `Equity`); the span between `from-date` and `to-date` must not exceed 9 months. Useful for building a calendar of market hours.", "parameters": [ { "in": "query", "name": "from-date", "description": "The date to start from", "required": false, "schema": { "type": "string", "format": "date", "default": "2026-10-26" }, "example": "2024-01-15" }, { "in": "query", "name": "instrument-collection", "description": "The instrument collection to get sessions for", "required": false, "schema": { "type": "string", "enum": [ "Equity", "CME", "CFE" ], "default": "Equity" }, "example": "Equity" }, { "in": "query", "name": "to-date", "description": "The date to end at, the difference between from and to date must not exceed 9 months", "required": true, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "An array of session timings, one per trading day in the requested range.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/SimpleSessionDeserializer" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/market-time/sessions" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "Invalid query parameters, for example a missing `to-date` or a `from-date`/`to-date` span that exceeds the 9-month maximum.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeSessions", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Sessions For Date Range" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /market-time/sessions/current — Get Current Sessions By Collection Returns the current trading session, plus its previous and next sessions, for an instrument collection supplied via the required `instrument-collections[]` query parameter (`CFE`, `CME`, or `Equity`). Use this to check the current market state. **Group:** Market Sessions · **operationId:** `getMarketTimeSessionsCurrent` **Required OAuth scope:** none. Applies to OAuth access tokens. ## Parameters - `instrument-collections` (query, required) — List of instrument collections . i.e. `CFE`, `CME` or `Equity` (example: instrument-collections[]={value1}&instrument-collections[]={value2}) ## Responses - `200` — The current session with its surrounding previous and next sessions. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `422` — Invalid or missing `instrument-collections[]` values. Allowed values are `CFE`, `CME`, and `Equity`. - `429` — Too many requests. Back off and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/market-time/sessions/current", "method": "get", "operation": { "description": "Returns the current trading session, plus its previous and next sessions, for an instrument collection supplied via the required `instrument-collections[]` query parameter (`CFE`, `CME`, or `Equity`). Use this to check the current market state.", "parameters": [ { "in": "query", "name": "instrument-collections", "description": "List of instrument collections . i.e. `CFE`, `CME` or `Equity` (example: instrument-collections[]={value1}&instrument-collections[]={value2})", "required": true, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string", "enum": [ "CFE", "CME", "Equity" ] } }, "example": [ "CFE" ] } ], "responses": { "200": { "description": "The current session with its surrounding previous and next sessions.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/CurrentSessionDeserializer" }, "context": { "type": "string", "example": "/market-time/sessions/current" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "Invalid or missing `instrument-collections[]` values. Allowed values are `CFE`, `CME`, and `Equity`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests. Back off and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "market-time" ], "operationId": "getMarketTimeSessionsCurrent", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Current Sessions By Collection" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{accountNumber}/net-liq/history — Get Net-Liq History For Account Returns the account's net liquidating value history (the total current value of the account — roughly the cash you would end up with if you closed every position) as open/high/low/close data. Use the `time-back` parameter for a window relative to now (`1d`, `1w`, `1m`, `3m`, `6m`, `1y`, `all`), or supply `start-time`/`end-time` for an explicit window. This is a read-only endpoint and moves no money. **Group:** Net Liquidating Value History · **operationId:** `getNetLiqHistory` ## Parameters - `accountNumber` (path, required) — - `time-back` (query) — A request of data relative to the current time - `start-time` (query) — The start-time of a windowed request in format '2011-12-03T10:15:30+01:00[Europe/Paris]' - `end-time` (query) — The end-time of a windowed request in format '2011-12-03T10:15:30+01:00[Europe/Paris]' - `interval` (query) — ## Responses - `200` — Net-liq history for the account over the requested window, as open/high/low/close data. - `401` — Missing or invalid authentication. Send a valid `Authorization: Bearer ` (access tokens last 15 minutes) and always include a `User-Agent` header in the form `/`. - `403` — Authenticated, but the token's scope or the account's authority level does not permit reading this account's net-liq history. - `404` — No account matches the supplied `accountNumber`, or the request was sent to the wrong environment (sandbox `api.cert.tastyworks.com` vs production `api.tastyworks.com`). - `429` — Request rate exceeded reasonable thresholds. Back off exponentially and reduce your request rate before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{accountNumber}/net-liq/history", "method": "get", "operation": { "tags": [ "net-liq-controller" ], "summary": "Get Net-Liq History For Account", "operationId": "getNetLiqHistory", "parameters": [ { "name": "accountNumber", "in": "path", "required": true, "schema": { "type": "string" } }, { "name": "time-back", "in": "query", "description": "A request of data relative to the current time", "required": false, "schema": { "type": "string", "enum": [ "1d", "1w", "1m", "3m", "6m", "1y", "all" ] }, "example": "1d" }, { "name": "start-time", "in": "query", "description": "The start-time of a windowed request in format '2011-12-03T10:15:30+01:00[Europe/Paris]'", "required": false, "schema": { "type": "string" } }, { "name": "end-time", "in": "query", "description": "The end-time of a windowed request in format '2011-12-03T10:15:30+01:00[Europe/Paris]'", "required": false, "schema": { "type": "string" } }, { "name": "interval", "in": "query", "required": false, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Net-liq history for the account over the requested window, as open/high/low/close data.", "content": { "*/*": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/NetLiqOhlc" }, "context": { "type": "string", "example": "/accounts/{accountNumber}/net-liq/history" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid authentication. Send a valid `Authorization: Bearer ` (access tokens last 15 minutes) and always include a `User-Agent` header in the form `/`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account's authority level does not permit reading this account's net-liq history.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account matches the supplied `accountNumber`, or the request was sent to the wrong environment (sandbox `api.cert.tastyworks.com` vs production `api.tastyworks.com`).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded reasonable thresholds. Back off exponentially and reduce your request rate before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "description": "Returns the account's net liquidating value history (the total current value of the account — roughly the cash you would end up with if you closed every position) as open/high/low/close data. Use the `time-back` parameter for a window relative to now (`1d`, `1w`, `1m`, `3m`, `6m`, `1y`, `all`), or supply `start-time`/`end-time` for an explicit window. This is a read-only endpoint and moves no money." } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/complex-orders — List Complex Orders Returns a paginated list of all complex (bracket) orders for the account, such as OTOCO, OCO, OTO, and PAIRS strategies. Each complex order wraps one or more component orders and, where applicable, a trigger order. Use the `page-offset` and `per-page` query parameters to page through results. **Group:** Orders · **operationId:** `getAccountsAccountNumberComplexOrders` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `page-offset` (query) — - `per-page` (query) — ## Responses - `200` — A paginated list of complex orders for the account. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — The account number does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders", "method": "get", "operation": { "description": "Returns a paginated list of all complex (bracket) orders for the account, such as OTOCO, OCO, OTO, and PAIRS strategies. Each complex order wraps one or more component orders and, where applicable, a trigger order. Use the `page-offset` and `per-page` query parameters to page through results.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 200, "default": 10 }, "example": 10 } ], "responses": { "200": { "description": "A paginated list of complex orders for the account.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/ComplexOrder" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "getAccountsAccountNumberComplexOrders", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Complex Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/complex-orders — Submit Complex Order Submits a new complex (bracket) order from the supplied parameters. Supported strategies are `OTOCO`, `OCO`, `OTO`, and `PAIRS` (`BLAST` is deprecated and unsupported). OTOCO and OTO orders include a `trigger-order` that routes immediately; the remaining `orders` stay in `Contingent` status until the trigger order fills. Run the dry-run endpoint first to validate the order. **Group:** Orders · **operationId:** `postAccountsAccountNumberComplexOrders` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `201` — The complex order was accepted. The response contains the overall complex order id plus an id for each component order, along with the buying-power and fee impact. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit placing orders on this account. - `404` — The account number does not exist or is not accessible with this token. - `422` — The complex order failed preflight validation. The response JSON's `error.message` (and `errors[]`) explain the rejection reason, for example a contingent leg with no existing position to close. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders", "method": "post", "operation": { "description": "Submits a new complex (bracket) order from the supplied parameters. Supported strategies are `OTOCO`, `OCO`, `OTO`, and `PAIRS` (`BLAST` is deprecated and unsupported). OTOCO and OTO orders include a `trigger-order` that routes immediately; the remaining `orders` stay in `Contingent` status until the trigger order fills. Run the dry-run endpoint first to validate the order.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberComplexOrders" } } }, "required": true }, "responses": { "201": { "description": "The complex order was accepted. The response contains the overall complex order id plus an id for each component order, along with the buying-power and fee impact.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit placing orders on this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The complex order failed preflight validation. The response JSON's `error.message` (and `errors[]`) explain the rejection reason, for example a contingent leg with no existing position to close.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "postAccountsAccountNumberComplexOrders", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Submit Complex Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/complex-orders/{id} — Get Complex Order Returns the full representation of a single complex order by its id, including its trigger order (if any), all component orders, and any related (replaced or terminal) orders. The `id` must be the complex order id, not a component or trigger order id. **Group:** Orders · **operationId:** `getAccountsAccountNumberComplexOrdersId` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The full complex order. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — No complex order with this id exists on the account. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/{id}", "method": "get", "operation": { "description": "Returns the full representation of a single complex order by its id, including its trigger order (if any), all component orders, and any related (replaced or terminal) orders. The `id` must be the complex order id, not a component or trigger order id.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The full complex order.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ComplexOrder" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No complex order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "getAccountsAccountNumberComplexOrdersId", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Complex Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # DELETE /accounts/{account_number}/complex-orders/{id} — Cancel Complex Order Requests cancellation of all non-terminal component orders of a complex order. The `id` must be the complex order id, not its trigger order id or any nested order id. Successfully requested components transition to `Cancel Requested` and then `Cancelled` once the exchange confirms. **Group:** Orders · **operationId:** `deleteAccountsAccountNumberComplexOrdersId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The complex order with its components transitioning to a cancelled state. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit cancelling this account's orders. - `404` — No complex order with this id exists on the account. - `422` — The complex order (or all its components) is already in a terminal status and cannot be cancelled. Read `error.message` for the reason. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/{id}", "method": "delete", "operation": { "description": "Requests cancellation of all non-terminal component orders of a complex order. The `id` must be the complex order id, not its trigger order id or any nested order id. Successfully requested components transition to `Cancel Requested` and then `Cancelled` once the exchange confirms.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The complex order with its components transitioning to a cancelled state.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ComplexOrder" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit cancelling this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No complex order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The complex order (or all its components) is already in a terminal status and cannot be cancelled. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "deleteAccountsAccountNumberComplexOrdersId", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": true, "x-rate-limit-bucket": "destructive", "summary": "Cancel Complex Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # PATCH /accounts/{account_number}/complex-orders/{id} — Edit PAIRS Complex Order Edits the ratio-price threshold (and its comparator) of a working PAIRS complex order. Only PAIRS orders can be edited through this endpoint. **Group:** Orders · **operationId:** `patchAccountsAccountNumberComplexOrdersId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The edited complex order, returned via a placed-order response with the updated ratio-price threshold. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit editing this account's orders. - `404` — No complex order with this id exists on the account. - `422` — The edit is invalid in context, for example the order is not a PAIRS order or is no longer editable. Read `error.message` for the reason. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/{id}", "method": "patch", "operation": { "description": "Edits the ratio-price threshold (and its comparator) of a working PAIRS complex order. Only PAIRS orders can be edited through this endpoint.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/patchAccountsAccountNumberComplexOrdersId" } } }, "required": true }, "responses": { "200": { "description": "The edited complex order, returned via a placed-order response with the updated ratio-price threshold.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit editing this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No complex order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The edit is invalid in context, for example the order is not a PAIRS order or is no longer editable. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "patchAccountsAccountNumberComplexOrdersId", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Edit PAIRS Complex Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/complex-orders/{id}/dry-run — Dry Run Complex Order Edit Validates an edit to an existing complex order (the ratio-price threshold of a PAIRS order) without routing it. Returns the preflight checks, warnings, buying-power effect, and fee estimate for the proposed edit. **Group:** Orders · **operationId:** `postAccountsAccountNumberComplexOrdersIdDryRun` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `201` — The dry-run for the proposed edit completed without routing it. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit this action. - `404` — No complex order with this id exists on the account. - `422` — The proposed edit failed preflight validation. Read `error.message` to fix the reason before submitting. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/{id}/dry-run", "method": "post", "operation": { "description": "Validates an edit to an existing complex order (the ratio-price threshold of a PAIRS order) without routing it. Returns the preflight checks, warnings, buying-power effect, and fee estimate for the proposed edit.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberComplexOrdersIdDryRun" } } }, "required": true }, "responses": { "201": { "description": "The dry-run for the proposed edit completed without routing it.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/{id}/dry-run" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit this action.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No complex order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The proposed edit failed preflight validation. Read `error.message` to fix the reason before submitting.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "postAccountsAccountNumberComplexOrdersIdDryRun", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Dry Run Complex Order Edit" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/complex-orders/dry-run — Dry Run Complex Order Validates a new complex order without routing it, returning the same preflight checks, warnings, buying-power effect, and fee estimate as a live submission. Submit the identical body to `POST /accounts/{account_number}/complex-orders` once it passes. **Group:** Orders · **operationId:** `postAccountsAccountNumberComplexOrdersDryRun` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `201` — The dry-run completed. The response contains warnings, the buying-power effect, and the fee calculation for the proposed complex order without placing it. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit this action. - `404` — The account number does not exist or is not accessible with this token. - `422` — The proposed complex order failed preflight validation. Read `error.message` (and `errors[]`) to fix the rejection reason before submitting. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/dry-run", "method": "post", "operation": { "description": "Validates a new complex order without routing it, returning the same preflight checks, warnings, buying-power effect, and fee estimate as a live submission. Submit the identical body to `POST /accounts/{account_number}/complex-orders` once it passes.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberComplexOrdersDryRun" } } }, "required": true }, "responses": { "201": { "description": "The dry-run completed. The response contains warnings, the buying-power effect, and the fee calculation for the proposed complex order without placing it.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/dry-run" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit this action.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The proposed complex order failed preflight validation. Read `error.message` (and `errors[]`) to fix the rejection reason before submitting.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "postAccountsAccountNumberComplexOrdersDryRun", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Dry Run Complex Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/complex-orders/live — List Today's Complex Orders Returns all complex orders that had a component order placed today, regardless of current status. Despite the `live` name, the response includes orders that were cancelled, rejected, or filled today as well as still-working orders. **Group:** Orders · **operationId:** `getAccountsAccountNumberComplexOrdersLive` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `200` — Complex orders with a component order placed during the current trading day. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — The account number does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/complex-orders/live", "method": "get", "operation": { "description": "Returns all complex orders that had a component order placed today, regardless of current status. Despite the `live` name, the response includes orders that were cancelled, rejected, or filled today as well as still-working orders.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "Complex orders with a component order placed during the current trading day.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/ComplexOrder" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/complex-orders/live" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "complex-orders" ], "operationId": "getAccountsAccountNumberComplexOrdersLive", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Today's Complex Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/orders — Search Orders Returns a paginated list of the account's orders, filterable by date range, underlying symbol, instrument type, and status. Results default to descending chronological order; pass `sort=Asc` to reverse. Use `page-offset` and `per-page` to page through results. At least one of `start-date` or `start-at` is required; a request that sends neither is rejected with a 400. **Group:** Orders · **operationId:** `getAccountsAccountNumberOrders` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `page-offset` (query) — - `per-page` (query) — - `end-at` (query) — DateTime end range for filtering orders in full date-time - `end-date` (query) — - `futures-symbol` (query) — Used to fetch both futures and futures options orders - `sort` (query) — The order to sort results in. Accepts `Desc` or `Asc`. Defaults to `Desc` - `start-at` (query) — DateTime start of the range for filtering orders, in full date-time format. At least one of `start-date` or `start-at` is required. - `start-date` (query) — Start date for filtering orders. At least one of `start-date` or `start-at` is required. - `status` (query) — (example: status[]={value1}&status[]={value2}) - `underlying-instrument-type` (query) — Underlying instrument type - `underlying-symbol` (query) — - `without-count` (query) — Skip calculating the total item count. When true, `total-items` and `total-pages` are null. ## Responses - `200` — A paginated list of the account's orders matching the filters. - `400` — Neither `start-date` nor `start-at` was supplied, or another query parameter failed validation. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — The account number does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders", "method": "get", "operation": { "description": "Returns a paginated list of the account's orders, filterable by date range, underlying symbol, instrument type, and status. Results default to descending chronological order; pass `sort=Asc` to reverse. Use `page-offset` and `per-page` to page through results. At least one of `start-date` or `start-at` is required; a request that sends neither is rejected with a 400.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 200, "default": 100 }, "example": 10 }, { "in": "query", "name": "end-at", "description": "DateTime end range for filtering orders in full date-time", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" }, { "in": "query", "name": "end-date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "futures-symbol", "description": "Used to fetch both futures and futures options orders", "required": false, "schema": { "type": "string" }, "example": "ESM3" }, { "in": "query", "name": "sort", "description": "The order to sort results in. Accepts `Desc` or `Asc`. Defaults to `Desc`", "required": false, "schema": { "type": "string", "enum": [ "Desc", "Asc" ], "default": "Desc" }, "example": "Desc" }, { "in": "query", "name": "start-at", "description": "DateTime start of the range for filtering orders, in full date-time format. At least one of `start-date` or `start-at` is required.", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" }, { "in": "query", "name": "start-date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15", "description": "Start date for filtering orders. At least one of `start-date` or `start-at` is required." }, { "in": "query", "name": "status", "description": " (example: status[]={value1}&status[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "Live", "Filled" ] }, { "in": "query", "name": "underlying-instrument-type", "description": "Underlying instrument type", "required": false, "schema": { "type": "string" }, "example": "Equity" }, { "in": "query", "name": "underlying-symbol", "required": false, "schema": { "type": "string" }, "example": "AAPL" }, { "in": "query", "name": "without-count", "description": "Skip calculating the total item count. When true, `total-items` and `total-pages` are null.", "required": false, "schema": { "type": "boolean", "default": false }, "example": true } ], "responses": { "200": { "description": "A paginated list of the account's orders matching the filters.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Order" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/orders" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "400": { "description": "Neither `start-date` nor `start-at` was supplied, or another query parameter failed validation.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "getAccountsAccountNumberOrders", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Search Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/orders — Submit Order Submits an order for the account and routes it to an exchange. The response includes the new order id, its status (often `Routed`), and the buying-power and fee impact. Run the same body through the dry-run endpoint first to confirm it will be accepted. **Group:** Orders · **operationId:** `postAccountsAccountNumberOrders` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `201` — The order was accepted and routed. The response wraps the order plus its buying-power effect and fee calculation. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit placing orders on this account. - `404` — The account number does not exist or is not accessible with this token. - `422` — The order failed one or more preflight checks (for example `cant_buy_for_credit`, an invalid symbol, or insufficient buying power). The reason is in the response JSON's `error.message` and `error.errors[]`. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders", "method": "post", "operation": { "description": "Submits an order for the account and routes it to an exchange. The response includes the new order id, its status (often `Routed`), and the buying-power and fee impact. Run the same body through the dry-run endpoint first to confirm it will be accepted.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberOrders" } } }, "required": true }, "responses": { "201": { "description": "The order was accepted and routed. The response wraps the order plus its buying-power effect and fee calculation.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit placing orders on this account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The order failed one or more preflight checks (for example `cant_buy_for_credit`, an invalid symbol, or insufficient buying power). The reason is in the response JSON's `error.message` and `error.errors[]`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "postAccountsAccountNumberOrders", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Submit Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/orders/{id} — Get Order Returns a single order by its id, including its legs, fills, current status, and tracking details. Use this to follow an order's progress through the submission, working, and terminal phases. **Group:** Orders · **operationId:** `getAccountsAccountNumberOrdersId` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The requested order. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — No order with this id exists on the account. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/{id}", "method": "get", "operation": { "description": "Returns a single order by its id, including its legs, fills, current status, and tracking details. Use this to follow an order's progress through the submission, working, and terminal phases.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The requested order.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Order" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "getAccountsAccountNumberOrdersId", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # PUT /accounts/{account_number}/orders/{id} — Replace Order Cancel-replaces a live order with a new one. Only `price`, `order-type`, and `time-in-force` may change; the rest of the body must match the original order. The replacement stays `Contingent` until the original is cancelled, and any fill of the original aborts the replacement. **Group:** Orders · **operationId:** `putAccountsAccountNumberOrdersId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The replacement order, typically `Contingent` until the original order is cancelled. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit editing this account's orders. - `404` — No order with this id exists on the account. - `422` — The order cannot be replaced (for example it is already in a terminal status) or the replacement failed preflight validation. Read `error.message` for the reason. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/{id}", "method": "put", "operation": { "description": "Cancel-replaces a live order with a new one. Only `price`, `order-type`, and `time-in-force` may change; the rest of the body must match the original order. The replacement stays `Contingent` until the original is cancelled, and any fill of the original aborts the replacement.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/putAccountsAccountNumberOrdersId" } } }, "required": true }, "responses": { "200": { "description": "The replacement order, typically `Contingent` until the original order is cancelled.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Order" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit editing this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The order cannot be replaced (for example it is already in a terminal status) or the replacement failed preflight validation. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "putAccountsAccountNumberOrdersId", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": true, "x-rate-limit-bucket": "destructive", "summary": "Replace Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # DELETE /accounts/{account_number}/orders/{id} — Cancel Order Requests cancellation of a live order. On success the order transitions to `Cancel Requested` while tastytrade confirms with the exchange, then to `Cancelled`. Cancelling an order that is already in a terminal status returns 422. **Group:** Orders · **operationId:** `deleteAccountsAccountNumberOrdersId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The order with a `Cancel Requested` status while the exchange confirms the cancellation. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit cancelling this account's orders. - `404` — No order with this id exists on the account. - `422` — The order is already in a terminal status and cannot be cancelled. The response JSON returns `error.code` `cannot_update_order` with the message 'the order could not be cancelled'. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/{id}", "method": "delete", "operation": { "description": "Requests cancellation of a live order. On success the order transitions to `Cancel Requested` while tastytrade confirms with the exchange, then to `Cancelled`. Cancelling an order that is already in a terminal status returns 422.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The order with a `Cancel Requested` status while the exchange confirms the cancellation.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Order" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit cancelling this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The order is already in a terminal status and cannot be cancelled. The response JSON returns `error.code` `cannot_update_order` with the message 'the order could not be cancelled'.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "deleteAccountsAccountNumberOrdersId", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": true, "x-rate-limit-bucket": "destructive", "summary": "Cancel Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # PATCH /accounts/{account_number}/orders/{id} — Edit Order Edits the price and execution properties of a live order by replacement. Only `price`, `order-type`, and `time-in-force` may change. As with a full replace, any fill of the original order aborts the edit. **Group:** Orders · **operationId:** `patchAccountsAccountNumberOrdersId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The edited (replacement) order. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit editing this account's orders. - `404` — No order with this id exists on the account. - `422` — The order cannot be edited (for example it is no longer editable) or the edit failed preflight validation. Read `error.message` for the reason. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/{id}", "method": "patch", "operation": { "description": "Edits the price and execution properties of a live order by replacement. Only `price`, `order-type`, and `time-in-force` may change. As with a full replace, any fill of the original order aborts the edit.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/patchAccountsAccountNumberOrdersId" } } }, "required": true }, "responses": { "200": { "description": "The edited (replacement) order.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Order" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit editing this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The order cannot be edited (for example it is no longer editable) or the edit failed preflight validation. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "patchAccountsAccountNumberOrdersId", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Edit Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/orders/{id}/dry-run — Dry Run Order Edit Runs the preflight checks for a cancel-replace or edit of an existing order without routing it. Use this to confirm a replacement order will be accepted before calling the `PUT` or `PATCH` endpoint. **Group:** Orders · **operationId:** `postAccountsAccountNumberOrdersIdDryRun` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `201` — The dry-run for the proposed replacement completed without routing it. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit this action. - `404` — No order with this id exists on the account. - `422` — The proposed replacement failed preflight validation. Read `error.message` to fix the rejection reason before submitting. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/{id}/dry-run", "method": "post", "operation": { "description": "Runs the preflight checks for a cancel-replace or edit of an existing order without routing it. Use this to confirm a replacement order will be accepted before calling the `PUT` or `PATCH` endpoint.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberOrdersIdDryRun" } } }, "required": true }, "responses": { "201": { "description": "The dry-run for the proposed replacement completed without routing it.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/{id}/dry-run" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit this action.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No order with this id exists on the account.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The proposed replacement failed preflight validation. Read `error.message` to fix the rejection reason before submitting.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "postAccountsAccountNumberOrdersIdDryRun", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Dry Run Order Edit" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /accounts/{account_number}/orders/dry-run — Dry Run Order Runs the full preflight checks for an order without routing it, returning warnings, the buying-power effect, and an estimated fee calculation. A warning here means the order would be rejected if actually submitted. When ready, post the identical body to `POST /accounts/{account_number}/orders`. **Group:** Orders · **operationId:** `postAccountsAccountNumberOrdersDryRun` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `201` — The dry-run completed. The response contains the proposed order, any warnings, the buying-power effect, and the fee calculation without placing the order. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit this action. - `404` — The account number does not exist or is not accessible with this token. - `422` — The proposed order failed preflight validation. Read `error.message` and `error.errors[]` to fix the rejection reason before submitting. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/dry-run", "method": "post", "operation": { "description": "Runs the full preflight checks for an order without routing it, returning warnings, the buying-power effect, and an estimated fee calculation. A warning here means the order would be rejected if actually submitted. When ready, post the identical body to `POST /accounts/{account_number}/orders`.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postAccountsAccountNumberOrdersDryRun" } } }, "required": true }, "responses": { "201": { "description": "The dry-run completed. The response contains the proposed order, any warnings, the buying-power effect, and the fee calculation without placing the order.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PlacedOrderResponse" }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/dry-run" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit this action.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The proposed order failed preflight validation. Read `error.message` and `error.errors[]` to fix the rejection reason before submitting.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "postAccountsAccountNumberOrdersDryRun", "x-tt-class": "money-moving", "x-money-moving": true, "x-idempotent": false, "x-rate-limit-bucket": "destructive", "summary": "Dry Run Order" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/orders/live — List Today's Orders Returns all orders that were created or updated during the current trading day, in any status. Despite the `live` name, the response also includes orders cancelled, rejected, filled, or expired today, plus older GTC orders that are still working. **Group:** Orders · **operationId:** `getAccountsAccountNumberOrdersLive` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `page-offset` (query) — - `per-page` (query) — - `status` (query) — (example: status[]={value1}&status[]={value2}) - `underlying-symbol` (query) — ## Responses - `200` — Orders created or updated during the current trading day. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope or the account authority does not permit reading this account's orders. - `404` — The account number does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/orders/live", "method": "get", "operation": { "description": "Returns all orders that were created or updated during the current trading day, in any status. Despite the `live` name, the response also includes orders cancelled, rejected, filled, or expired today, plus older GTC orders that are still working.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 200, "default": 100 }, "example": 10 }, { "in": "query", "name": "status", "description": " (example: status[]={value1}&status[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string", "enum": [ "Cancelled", "Cancel Requested", "Contingent", "Expired", "Filled", "In Flight", "Live", "Partially Removed", "Received", "Rejected", "Removed", "Replace Requested", "Routed" ] } }, "example": [ "Cancelled" ] }, { "in": "query", "name": "underlying-symbol", "required": false, "schema": { "type": "string" }, "example": "AAPL" } ], "responses": { "200": { "description": "Orders created or updated during the current trading day.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Order" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/orders/live" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope or the account authority does not permit reading this account's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The account number does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "getAccountsAccountNumberOrdersLive", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Today's Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /customers/{customer_id}/orders — Search Customer Orders Returns a paginated list of orders across all of the customer's accounts, filterable by date range, underlying symbol, instrument type, and status. Results default to descending chronological order; pass `sort=Asc` to reverse. Use `page-offset` and `per-page` to page through results. At least one of `start-date` or `start-at` is required; a request that sends neither is rejected with a 400. **Group:** Orders · **operationId:** `getCustomersCustomerIdOrders` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `customer_id` (path, required) — - `account-numbers` (query, required) — The account numbers to use for the lookup (example: account-numbers[]={value1}&account-numbers[]={value2}) - `page-offset` (query) — - `per-page` (query) — - `end-at` (query) — DateTime end range for filtering orders in full date-time - `end-date` (query) — - `futures-symbol` (query) — Used to fetch both futures and futures options orders - `sort` (query) — The order to sort results in. Accepts `Desc` or `Asc`. Defaults to `Desc` - `start-at` (query) — DateTime start of the range for filtering orders, in full date-time format. At least one of `start-date` or `start-at` is required. - `start-date` (query) — Start date for filtering orders. At least one of `start-date` or `start-at` is required. - `status` (query) — (example: status[]={value1}&status[]={value2}) - `underlying-instrument-type` (query) — Underlying instrument type - `underlying-symbol` (query) — - `without-count` (query) — Skip calculating the total item count. When true, `total-items` and `total-pages` are null. ## Responses - `200` — A paginated list of the customer's orders matching the filters. - `400` — Neither `start-date` nor `start-at` was supplied, or another query parameter failed validation. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope does not permit reading this customer's orders. - `404` — The customer id does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/customers/{customer_id}/orders", "method": "get", "operation": { "description": "Returns a paginated list of orders across all of the customer's accounts, filterable by date range, underlying symbol, instrument type, and status. Results default to descending chronological order; pass `sort=Asc` to reverse. Use `page-offset` and `per-page` to page through results. At least one of `start-date` or `start-at` is required; a request that sends neither is rejected with a 400.", "parameters": [ { "in": "path", "name": "customer_id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 }, { "in": "query", "name": "account-numbers", "description": "The account numbers to use for the lookup (example: account-numbers[]={value1}&account-numbers[]={value2})", "required": true, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "5WX01234" ] }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 200, "default": 100 }, "example": 10 }, { "in": "query", "name": "end-at", "description": "DateTime end range for filtering orders in full date-time", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" }, { "in": "query", "name": "end-date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "futures-symbol", "description": "Used to fetch both futures and futures options orders", "required": false, "schema": { "type": "string" }, "example": "ESM3" }, { "in": "query", "name": "sort", "description": "The order to sort results in. Accepts `Desc` or `Asc`. Defaults to `Desc`", "required": false, "schema": { "type": "string", "enum": [ "Desc", "Asc" ], "default": "Desc" }, "example": "Desc" }, { "in": "query", "name": "start-at", "description": "DateTime start of the range for filtering orders, in full date-time format. At least one of `start-date` or `start-at` is required.", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" }, { "in": "query", "name": "start-date", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15", "description": "Start date for filtering orders. At least one of `start-date` or `start-at` is required." }, { "in": "query", "name": "status", "description": " (example: status[]={value1}&status[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "Live", "Filled" ] }, { "in": "query", "name": "underlying-instrument-type", "description": "Underlying instrument type", "required": false, "schema": { "type": "string" }, "example": "Equity" }, { "in": "query", "name": "underlying-symbol", "required": false, "schema": { "type": "string" }, "example": "AAPL" }, { "in": "query", "name": "without-count", "description": "Skip calculating the total item count. When true, `total-items` and `total-pages` are null.", "required": false, "schema": { "type": "boolean", "default": false }, "example": true } ], "responses": { "200": { "description": "A paginated list of the customer's orders matching the filters.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Order" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/customers/{customer_id}/orders" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "400": { "description": "Neither `start-date` nor `start-at` was supplied, or another query parameter failed validation.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope does not permit reading this customer's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The customer id does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "getCustomersCustomerIdOrders", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Search Customer Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /customers/{customer_id}/orders/live — List Customer's Today's Orders Returns a paginated list of orders from the current trading day for the given account numbers, in any status, not only `Live`. Use `page-offset` and `per-page` to page through results (default 100 per page, maximum 200); the response carries a top-level `pagination` block. In API version `20250813` this endpoint is not paginated and returns every order in a single response. **Group:** Orders · **operationId:** `getCustomersCustomerIdOrdersLive` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `customer_id` (path, required) — - `account-numbers` (query, required) — The account numbers to use for the lookup (example: account-numbers[]={value1}&account-numbers[]={value2}) - `page-offset` (query) — Which page to fetch. `0` is the first page. - `per-page` (query) — The number of orders per page. Defaults to 100; maximum 200. ## Responses - `200` — A page of the customer's orders from the current trading day. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. - `403` — The token's scope does not permit reading this customer's orders. - `404` — The customer id does not exist or is not accessible with this token. - `429` — Request rate exceeded. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/customers/{customer_id}/orders/live", "method": "get", "operation": { "description": "Returns a paginated list of orders from the current trading day for the given account numbers, in any status, not only `Live`. Use `page-offset` and `per-page` to page through results (default 100 per page, maximum 200); the response carries a top-level `pagination` block. In API version `20250813` this endpoint is not paginated and returns every order in a single response.", "parameters": [ { "in": "path", "name": "customer_id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 }, { "in": "query", "name": "account-numbers", "description": "The account numbers to use for the lookup (example: account-numbers[]={value1}&account-numbers[]={value2})", "required": true, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } }, "example": [ "5WX01234" ] }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10, "description": "Which page to fetch. `0` is the first page." }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 200, "default": 100 }, "example": 10, "description": "The number of orders per page. Defaults to 100; maximum 200." } ], "responses": { "200": { "description": "A page of the customer's orders from the current trading day.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Order" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/customers/{customer_id}/orders/live" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "The token's scope does not permit reading this customer's orders.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "The customer id does not exist or is not accessible with this token.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "orders" ], "operationId": "getCustomersCustomerIdOrdersLive", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Customer's Today's Orders" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /quote-alerts — List Quote Alerts Returns quote alerts for the authenticated user. Use it to render an alert dashboard or to reconcile local state before creating or cancelling alerts. **Group:** Quote Alerts · **operationId:** `getQuoteAlerts` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `200` — The authenticated user's quote alerts. - `401` — Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`. - `429` — Too many requests in a short period. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/quote-alerts", "method": "get", "operation": { "description": "Returns quote alerts for the authenticated user. Use it to render an alert dashboard or to reconcile local state before creating or cancelling alerts.", "responses": { "200": { "description": "The authenticated user's quote alerts.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/QuoteAlertDeserializer" }, "context": { "type": "string", "example": "/quote-alerts" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Too many requests in a short period. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "quote-alerts" ], "operationId": "getQuoteAlerts", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Quote Alerts" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /quote-alerts — Create Quote Alert Creates a quote alert for a symbol. Provide a `field` (`Last`, `Bid`, `Ask`, or `IV`), an `operator` (`>` or `<`), the `symbol`, and a `threshold` the watched field is compared against. Keys are dasherized and the request body must be JSON. **Group:** Quote Alerts · **operationId:** `postQuoteAlerts` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters _None_ ## Responses - `201` — The newly created quote alert. - `401` — Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`. - `422` — The alert could not be created — for example a missing required field or an unrecognized `field`/`operator` value. The reason is in the response JSON's `error.message`. - `429` — Too many requests in a short period. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/quote-alerts", "method": "post", "operation": { "description": "Creates a quote alert for a symbol. Provide a `field` (`Last`, `Bid`, `Ask`, or `IV`), an `operator` (`>` or `<`), the `symbol`, and a `threshold` the watched field is compared against. Keys are dasherized and the request body must be JSON.", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postQuoteAlerts" } } }, "required": true }, "responses": { "201": { "description": "The newly created quote alert.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/QuoteAlertDeserializer" }, "context": { "type": "string", "example": "/quote-alerts" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "422": { "description": "The alert could not be created — for example a missing required field or an unrecognized `field`/`operator` value. The reason is in the response JSON's `error.message`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Too many requests in a short period. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "quote-alerts" ], "operationId": "postQuoteAlerts", "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": false, "x-rate-limit-bucket": "write", "summary": "Create Quote Alert" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # DELETE /quote-alerts/{alert_external_id} — Cancel Quote Alert Cancels (deletes) the quote alert identified by its `alert_external_id` for the authenticated user. On success the alert is no longer active and the endpoint returns an empty `204 No Content` response. This operation is idempotent. **Group:** Quote Alerts · **operationId:** `deleteQuoteAlertsAlertExternalId` **Required OAuth scope:** `trade`. Applies to OAuth access tokens. ## Parameters - `alert_external_id` (path, required) — ## Responses - `204` — The quote alert was cancelled successfully. No response body is returned. - `401` — Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`. - `403` — Authenticated, but the token's scope or account authority does not permit cancelling this alert. - `404` — No quote alert exists for the supplied `alert_external_id`. - `429` — Too many requests in a short period. Back off exponentially and reduce your request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/quote-alerts/{alert_external_id}", "method": "delete", "operation": { "description": "Cancels (deletes) the quote alert identified by its `alert_external_id` for the authenticated user. On success the alert is no longer active and the endpoint returns an empty `204 No Content` response. This operation is idempotent.", "parameters": [ { "in": "path", "name": "alert_external_id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "204": { "description": "The quote alert was cancelled successfully. No response body is returned." }, "401": { "description": "Missing, expired, or invalid access token, or a missing/malformed `User-Agent` header. Send `Authorization: Bearer ` (tokens last 15 minutes) and a `User-Agent` like `my-app/1.0`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or account authority does not permit cancelling this alert.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No quote alert exists for the supplied `alert_external_id`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Too many requests in a short period. Back off exponentially and reduce your request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "quote-alerts" ], "operationId": "deleteQuoteAlertsAlertExternalId", "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "write", "summary": "Cancel Quote Alert" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/expected-price-ranges/equity/{underlying_symbol}/effective — getAccountsAccountNumberExpectedPriceRangesEquityUnderlyingSymbolEffective Get effective expected price range for account and equity underlying **Group:** Risk Parameters · **operationId:** `getAccountsAccountNumberExpectedPriceRangesEquityUnderlyingSymbolEffective` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `underlying_symbol` (path, required) — ## Responses - `200` — Get effective expected price range for account and equity underlying # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/expected-price-ranges/equity/{underlying_symbol}/effective", "method": "get", "operation": { "description": "Get effective expected price range for account and equity underlying", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "underlying_symbol", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Get effective expected price range for account and equity underlying", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ExpectedPriceRange" }, "context": { "type": "string", "example": "/accounts/{account_number}/expected-price-ranges/equity/{underlying_symbol}/effective" } }, "required": [ "data", "context" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberExpectedPriceRangesEquityUnderlyingSymbolEffective", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/expected-price-ranges/future/{underlying_symbol}/effective — getAccountsAccountNumberExpectedPriceRangesFutureUnderlyingSymbolEffective Get effective expected price range for account and future underlying **Group:** Risk Parameters · **operationId:** `getAccountsAccountNumberExpectedPriceRangesFutureUnderlyingSymbolEffective` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `underlying_symbol` (path, required) — ## Responses - `200` — Get effective expected price range for account and future underlying # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/expected-price-ranges/future/{underlying_symbol}/effective", "method": "get", "operation": { "description": "Get effective expected price range for account and future underlying", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "underlying_symbol", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Get effective expected price range for account and future underlying", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/ExpectedPriceRange" }, "context": { "type": "string", "example": "/accounts/{account_number}/expected-price-ranges/future/{underlying_symbol}/effective" } }, "required": [ "data", "context" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberExpectedPriceRangesFutureUnderlyingSymbolEffective", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/margin-requirements/{underlying_symbol}/effective — Get Effective Margin Requirements Returns the margin requirements in effect for a single underlying symbol on the given account. **Group:** Risk Parameters · **operationId:** `getAccountsAccountNumberMarginRequirementsUnderlyingSymbolEffective` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `underlying_symbol` (path, required) — ## Responses - `200` — The effective margin requirement rates for the underlying on this account. - `401` — Missing or expired access token. Tokens last 15 minutes and must be sent on every request. Note: a missing or malformed `User-Agent` header also produces a 401, but it is returned as an HTML error page from the proxy layer rather than this JSON error body. - `403` — Authenticated, but the token's scope or the account authority does not permit reading this account's margin requirements. - `404` — No account exists for the supplied `account_number`, or no effective margin requirement exists for the given `underlying_symbol`. - `429` — Rate limit exceeded. Back off exponentially and reduce the request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/margin-requirements/{underlying_symbol}/effective", "method": "get", "operation": { "description": "Returns the margin requirements in effect for a single underlying symbol on the given account.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "underlying_symbol", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The effective margin requirement rates for the underlying on this account.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/MarginRequirement" }, "context": { "type": "string", "example": "/accounts/{account_number}/margin-requirements/{underlying_symbol}/effective" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token. Tokens last 15 minutes and must be sent on every request. Note: a missing or malformed `User-Agent` header also produces a 401, but it is returned as an HTML error page from the proxy layer rather than this JSON error body.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account authority does not permit reading this account's margin requirements.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account exists for the supplied `account_number`, or no effective margin requirement exists for the given `underlying_symbol`.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially and reduce the request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberMarginRequirementsUnderlyingSymbolEffective", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Effective Margin Requirements" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/position-limit — Get Account Position Limit Returns the position and order size limits configured for an account, broken out by instrument type (equities, equity options, futures, and future options). Use this to validate order and position sizing before submitting orders. **Group:** Risk Parameters · **operationId:** `getAccountsAccountNumberPositionLimit` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — ## Responses - `200` — The account's position and order size limits. - `401` — Missing or expired access token. Tokens last 15 minutes and must be sent on every request. Note: a missing or malformed `User-Agent` header also produces a 401, but it is returned as an HTML error page from the proxy layer rather than this JSON error body. - `403` — Authenticated, but the token's scope or the account authority does not permit reading this account's position limit. - `404` — No account exists for the supplied `account_number`, or it is not visible under the authenticated customer. - `429` — Rate limit exceeded. Back off exponentially and reduce the request rate. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/position-limit", "method": "get", "operation": { "description": "Returns the position and order size limits configured for an account, broken out by instrument type (equities, equity options, futures, and future options). Use this to validate order and position sizing before submitting orders.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" } ], "responses": { "200": { "description": "The account's position and order size limits.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PositionLimit" }, "context": { "type": "string", "example": "/accounts/{account_number}/position-limit" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token. Tokens last 15 minutes and must be sent on every request. Note: a missing or malformed `User-Agent` header also produces a 401, but it is returned as an HTML error page from the proxy layer rather than this JSON error body.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or the account authority does not permit reading this account's position limit.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No account exists for the supplied `account_number`, or it is not visible under the authenticated customer.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially and reduce the request rate.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberPositionLimit", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Account Position Limit" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /symbols/search/{symbol} — Search Symbols Search tastytrade's tradeable instruments by symbol or symbol fragment — for example, searching `AAP` returns both `AAP` and `AAPL` — letting you power type-ahead and symbol-picker experiences. Each match returns lightweight metadata such as the company name, listed market, instrument type, and whether the symbol has listed options. This is a read-only lookup; use the full `/instruments/...` endpoints once you know the exact symbol you want to trade. **Group:** Symbol Search · **operationId:** `searchSymbols` ## Parameters - `symbol` (path, required) — Symbol or fragment of a symbol to search, i.e. `AAP` will return AAP and AAPL data ## Responses - `200` — Returns an array of symbol data for instruments matching the search term. - `401` — Missing or expired access token, or a missing/malformed `User-Agent` header. tastytrade requires a `User-Agent` in `/` form and a valid `Authorization: Bearer ` (tokens expire after 15 minutes) on every request. - `403` — Authenticated, but the token's OAuth scope does not permit reading instrument data. - `429` — Request rate exceeded. Back off exponentially and reduce your polling rate before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/symbols/search/{symbol}", "method": "get", "operation": { "description": "Search tastytrade's tradeable instruments by symbol or symbol fragment — for example, searching `AAP` returns both `AAP` and `AAPL` — letting you power type-ahead and symbol-picker experiences. Each match returns lightweight metadata such as the company name, listed market, instrument type, and whether the symbol has listed options. This is a read-only lookup; use the full `/instruments/...` endpoints once you know the exact symbol you want to trade.", "responses": { "200": { "description": "Returns an array of symbol data for instruments matching the search term.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/SymbolData" }, "context": { "type": "string", "example": "/symbols/search/{symbol}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or expired access token, or a missing/malformed `User-Agent` header. tastytrade requires a `User-Agent` in `/` form and a valid `Authorization: Bearer ` (tokens expire after 15 minutes) on every request.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's OAuth scope does not permit reading instrument data.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "429": { "description": "Request rate exceeded. Back off exponentially and reduce your polling rate before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "parameters": [ { "in": "path", "name": "symbol", "required": true, "description": "Symbol or fragment of a symbol to search, i.e. `AAP` will return AAP and AAPL data", "schema": { "type": "string" }, "example": "AAP" } ], "operationId": "searchSymbols", "tags": [ "symbol-search" ], "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Search Symbols" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/transactions — List Account Transactions Returns a paginated list of an account's transactions — orders, cash movements, position transfers, dividends, interest, and other ledger events. Results default to descending order (newest first); use the query parameters to page, sort, and filter by date range, symbol, instrument type, action, or transaction type. Note that `type` and `types` are mutually exclusive — supply one or the other, not both. **Group:** Transactions · **operationId:** `getAccountsAccountNumberTransactions` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `page-offset` (query) — - `per-page` (query) — - `currency` (query) — Currency - `sort` (query) — The order to sort results in. Defaults to Desc, Accepts `Desc` or `Asc`. - `sub-type` (query) — Filter based on transaction_sub_type (example: sub-type[]={value1}&sub-type[]={value2}) - `type` (query) — Filter based on transaction_type - `types` (query) — Allows filtering on multiple transaction_types (example: types[]={value1}&types[]={value2}) - `action` (query) — The action of the transaction. i.e. `Allocate`, `Buy`, `Buy to Close`, `Buy to Open`, `Sell`, `Sell to Close` or `Sell to Open` - `end-date` (query) — The end date of transactions to query. Defaults to now. - `futures-symbol` (query) — The full TW Future Symbol `/ESZ9` or \ `/NGZ19` if two year digit are appropriate - `instrument-type` (query) — The type of Instrument. i.e. `Bond`, `Cryptocurrency`, `Currency Pair`, `Equity`, `Equity Offering`, `Equity Option`, `Event Contract`, `Fixed Income Security`, `Future`, `Future Option`, `Index`, `Liquidity Pool`, `Unknown` or `Warrant` - `partition-key` (query) — Account partition key - `start-date` (query) — The start date of transactions to query. - `symbol` (query) — The Stock Ticker Symbol `AAPL`, OCC Option Symbol `AAPL 191004P00275000`, \ TW Future Symbol `/ESZ9`, or TW Future Option Symbol `./ESZ9 EW4U9 190927P2975` - `underlying-symbol` (query) — The Underlying Symbol. The Ticker Symbol `FB` or \ TW Future Symbol with out date component `/M6E` or the full TW Future Symbol `/ESU9` - `end-at` (query) — DateTime end range for filtering transactions in full date-time - `start-at` (query) — DateTime start range for filtering transactions in full date-time ## Responses - `200` — A paginated list of transactions wrapped in the standard envelope, with an `items` array and a `pagination` block describing the current page. - `401` — Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid (access tokens last 15 minutes), or the required `User-Agent: /` header is missing or malformed. - `403` — Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's transactions. - `404` — Not Found — no account matches the supplied `account_number`, or the wrong environment is being used (sandbox vs production). - `429` — Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially and page steadily rather than bursting. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/transactions", "method": "get", "operation": { "description": "Returns a paginated list of an account's transactions — orders, cash movements, position transfers, dividends, interest, and other ledger events. Results default to descending order (newest first); use the query parameters to page, sort, and filter by date range, symbol, instrument type, action, or transaction type. Note that `type` and `types` are mutually exclusive — supply one or the other, not both.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "query", "name": "page-offset", "required": false, "schema": { "type": "integer", "format": "int32", "default": 0 }, "example": 10 }, { "in": "query", "name": "per-page", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 1, "maximum": 2000, "default": 250 }, "example": 10 }, { "in": "query", "name": "currency", "description": "Currency", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "sort", "description": "The order to sort results in. Defaults to Desc, Accepts `Desc` or `Asc`.", "required": false, "schema": { "type": "string", "enum": [ "Desc", "Asc" ], "default": "Desc" }, "example": "Desc" }, { "in": "query", "name": "sub-type", "description": "Filter based on transaction_sub_type (example: sub-type[]={value1}&sub-type[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } } }, { "in": "query", "name": "type", "description": "Filter based on transaction_type", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "types", "description": "Allows filtering on multiple transaction_types (example: types[]={value1}&types[]={value2})", "required": false, "style": "form", "explode": true, "schema": { "type": "array", "items": { "type": "string" } } }, { "in": "query", "name": "action", "description": "The action of the transaction. i.e. `Allocate`, `Buy`, `Buy to Close`, `Buy to Open`, `Sell`, `Sell to Close` or `Sell to Open`", "required": false, "schema": { "type": "string" }, "example": "Allocate" }, { "in": "query", "name": "end-date", "description": "The end date of transactions to query. Defaults to now.", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "futures-symbol", "description": "The full TW Future Symbol `/ESZ9` or \\\n `/NGZ19` if two year digit are appropriate", "required": false, "schema": { "type": "string" }, "example": "/ESZ9" }, { "in": "query", "name": "instrument-type", "description": "The type of Instrument. i.e. `Bond`, `Cryptocurrency`, `Currency Pair`, `Equity`, `Equity Offering`, `Equity Option`, `Event Contract`, `Fixed Income Security`, `Future`, `Future Option`, `Index`, `Liquidity Pool`, `Unknown` or `Warrant`", "required": false, "schema": { "type": "string" }, "example": "Bond" }, { "in": "query", "name": "partition-key", "description": "Account partition key", "required": false, "schema": { "type": "string" } }, { "in": "query", "name": "start-date", "description": "The start date of transactions to query.", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" }, { "in": "query", "name": "symbol", "description": "The Stock Ticker Symbol `AAPL`, OCC Option Symbol `AAPL 191004P00275000`, \\\n TW Future Symbol `/ESZ9`, or TW Future Option Symbol `./ESZ9 EW4U9 190927P2975`", "required": false, "schema": { "type": "string" }, "example": "AAPL" }, { "in": "query", "name": "underlying-symbol", "description": "The Underlying Symbol. The Ticker Symbol `FB` or \\\n TW Future Symbol with out date component `/M6E` or\n the full TW Future Symbol `/ESU9`", "required": false, "schema": { "type": "string" }, "example": "FB" }, { "in": "query", "name": "end-at", "description": "DateTime end range for filtering transactions in full date-time", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" }, { "in": "query", "name": "start-at", "description": "DateTime start range for filtering transactions in full date-time", "required": false, "schema": { "type": "string", "format": "date-time" }, "example": "2024-01-15T14:30:00.000Z" } ], "responses": { "200": { "description": "A paginated list of transactions wrapped in the standard envelope, with an `items` array and a `pagination` block describing the current page.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Transaction" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/accounts/{account_number}/transactions" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid (access tokens last 15 minutes), or the required `User-Agent: /` header is missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's transactions.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Not Found — no account matches the supplied `account_number`, or the wrong environment is being used (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially and page steadily rather than bursting.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "transactions" ], "operationId": "getAccountsAccountNumberTransactions", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Account Transactions" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/transactions/{id} — Get Transaction By ID Retrieves a single transaction on the account by its numeric transaction `id`. Use this to fetch the full detail of one ledger event after locating it in the list endpoint. **Group:** Transactions · **operationId:** `getAccountsAccountNumberTransactionsId` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `id` (path, required) — ## Responses - `200` — The requested transaction, wrapped in the standard envelope. - `401` — Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid, or the required `User-Agent: /` header is missing or malformed. - `403` — Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's transactions. - `404` — Not Found — no transaction matches the supplied `id` on this account, no account matches `account_number`, or the wrong environment is being used (sandbox vs production). - `429` — Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/transactions/{id}", "method": "get", "operation": { "description": "Retrieves a single transaction on the account by its numeric transaction `id`. Use this to fetch the full detail of one ledger event after locating it in the list endpoint.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "path", "name": "id", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The requested transaction, wrapped in the standard envelope.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Transaction" }, "context": { "type": "string", "example": "/accounts/{account_number}/transactions/{id}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid, or the required `User-Agent: /` header is missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's transactions.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Not Found — no transaction matches the supplied `id` on this account, no account matches `account_number`, or the wrong environment is being used (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberTransactionsId", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Transaction By ID" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /accounts/{account_number}/transactions/total-fees — Get Total Fees For A Day Returns the total fees charged on an account for a single day. Pass `date` to choose the day (defaults to today). The response reports the aggregated fee amount and its direction via `total-fees-effect`. **Group:** Transactions · **operationId:** `getAccountsAccountNumberTransactionsTotalFees` **Required OAuth scope:** `read`. Applies to OAuth access tokens. ## Parameters - `account_number` (path, required) — - `date` (query) — The date to get fees for, defaults to today ## Responses - `200` — The aggregated fees for the requested day, wrapped in the standard envelope. - `401` — Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid, or the required `User-Agent: /` header is missing or malformed. - `403` — Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's fees. - `404` — Not Found — no account matches the supplied `account_number`, or the wrong environment is being used (sandbox vs production). - `429` — Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/accounts/{account_number}/transactions/total-fees", "method": "get", "operation": { "description": "Returns the total fees charged on an account for a single day. Pass `date` to choose the day (defaults to today). The response reports the aggregated fee amount and its direction via `total-fees-effect`.", "parameters": [ { "in": "path", "name": "account_number", "required": true, "schema": { "type": "string" }, "example": "5WX01234" }, { "in": "query", "name": "date", "description": "The date to get fees for, defaults to today", "required": false, "schema": { "type": "string", "format": "date" }, "example": "2024-01-15" } ], "responses": { "200": { "description": "The aggregated fees for the requested day, wrapped in the standard envelope.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "total-fees": { "type": "string", "format": "decimal", "description": "The total fees charged on the account for the requested day, returned as a string decimal.", "example": "100.0" }, "total-fees-effect": { "type": "string", "description": "The direction of `total-fees`: `Credit`, `Debit`, or `None`.", "example": "Debit" } } }, "context": { "type": "string", "example": "/accounts/{account_number}/transactions/total-fees" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Unauthorized — the `Authorization: Bearer ` header is missing, expired, or invalid, or the required `User-Agent: /` header is missing or malformed.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Forbidden — the token is valid but its scope or the account's authority level does not permit reading this account's fees.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "Not Found — no account matches the supplied `account_number`, or the wrong environment is being used (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Too Many Requests — the request rate exceeded the read rate limit. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "accounts" ], "operationId": "getAccountsAccountNumberTransactionsTotalFees", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Total Fees For A Day" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /pairs-watchlists — List Pairs Watchlists Returns every read-only tastytrade-published pairs watchlist. Each pairs watchlist groups related instruments via `pairs-equations` for pairs-trading analysis. **Group:** Watchlists · **operationId:** `getPairsWatchlists` ## Parameters _None_ ## Responses - `200` — A list of all tastytrade pairs watchlists. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/pairs-watchlists", "method": "get", "operation": { "description": "Returns every read-only tastytrade-published pairs watchlist. Each pairs watchlist groups related instruments via `pairs-equations` for pairs-trading analysis.", "responses": { "200": { "description": "A list of all tastytrade pairs watchlists.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/PairsWatchlist" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/pairs-watchlists" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "pairs-watchlists" ], "operationId": "getPairsWatchlists", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Pairs Watchlists" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /pairs-watchlists/{pairs_watchlist_name} — Get Pairs Watchlist Returns a single read-only tastytrade pairs watchlist, including its `pairs-equations`. **Group:** Watchlists · **operationId:** `getPairsWatchlistsPairsWatchlistName` ## Parameters - `pairs_watchlist_name` (path, required) — ## Responses - `200` — The requested pairs watchlist. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `404` — The requested pairs watchlist was not found. Verify the identifier and the environment (sandbox vs production). - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/pairs-watchlists/{pairs_watchlist_name}", "method": "get", "operation": { "description": "Returns a single read-only tastytrade pairs watchlist, including its `pairs-equations`.", "parameters": [ { "in": "path", "name": "pairs_watchlist_name", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The requested pairs watchlist.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/PairsWatchlist" }, "context": { "type": "string", "example": "/pairs-watchlists/{pairs_watchlist_name}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "The requested pairs watchlist was not found. Verify the identifier and the environment (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "pairs-watchlists" ], "operationId": "getPairsWatchlistsPairsWatchlistName", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Pairs Watchlist" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /public-watchlists — List Public Watchlists Returns every read-only tastytrade-published ("public") watchlist available to all clients. An optional boolean `counts-only` query parameter (default `false`) is supported. **Group:** Watchlists · **operationId:** `getPublicWatchlists` ## Parameters - `counts-only` (query) — ## Responses - `200` — A list of all tastytrade public watchlists. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/public-watchlists", "method": "get", "operation": { "description": "Returns every read-only tastytrade-published (\"public\") watchlist available to all clients. An optional boolean `counts-only` query parameter (default `false`) is supported.", "parameters": [ { "in": "query", "name": "counts-only", "required": false, "schema": { "type": "boolean", "default": false }, "example": true } ], "responses": { "200": { "description": "A list of all tastytrade public watchlists.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Watchlist" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/public-watchlists" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "public-watchlists" ], "operationId": "getPublicWatchlists", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Public Watchlists" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /public-watchlists/{watchlist_name} — Get Public Watchlist Returns a single read-only tastytrade public watchlist along with its full `watchlist-entries`. **Group:** Watchlists · **operationId:** `getPublicWatchlistsWatchlistName` ## Parameters - `watchlist_name` (path, required) — ## Responses - `200` — The requested public watchlist. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `404` — The requested public watchlist was not found. Verify the identifier and the environment (sandbox vs production). - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/public-watchlists/{watchlist_name}", "method": "get", "operation": { "description": "Returns a single read-only tastytrade public watchlist along with its full `watchlist-entries`.", "parameters": [ { "in": "path", "name": "watchlist_name", "required": true, "schema": { "type": "integer", "format": "int32" }, "example": 1 } ], "responses": { "200": { "description": "The requested public watchlist.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Watchlist" }, "context": { "type": "string", "example": "/public-watchlists/{watchlist_name}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "The requested public watchlist was not found. Verify the identifier and the environment (sandbox vs production).", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "public-watchlists" ], "operationId": "getPublicWatchlistsWatchlistName", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Public Watchlist" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /watchlists — List Watchlists Returns every watchlist belonging to the authenticated user, each with its full `watchlist-entries`. **Group:** Watchlists · **operationId:** `getWatchlists` ## Parameters _None_ ## Responses - `200` — A list of all of the user's watchlists. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/watchlists", "method": "get", "operation": { "description": "Returns every watchlist belonging to the authenticated user, each with its full `watchlist-entries`.", "responses": { "200": { "description": "A list of all of the user's watchlists.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "items": { "type": "array", "items": { "$ref": "#/components/schemas/Watchlist" } } }, "required": [ "items" ] }, "context": { "type": "string", "example": "/watchlists" }, "pagination": { "type": "object", "description": "Paging metadata, present on paginated list responses.", "properties": { "per-page": { "type": "integer" }, "page-offset": { "type": "integer" }, "item-offset": { "type": "integer" }, "total-items": { "type": "integer" }, "total-pages": { "type": "integer" }, "current-item-count": { "type": "integer" } } } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "user-watchlists" ], "operationId": "getWatchlists", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "List Watchlists" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # POST /watchlists — Create Watchlist Creates a new watchlist for the authenticated user. The body requires `name` and `watchlist-entries`; each entry requires a `symbol`, and `instrument-type` is optional. **Group:** Watchlists · **operationId:** `postWatchlists` ## Parameters _None_ ## Responses - `201` — The watchlist was created and is returned as stored. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `403` — Authenticated, but the token's scope or account authority does not permit creating watchlists. - `422` — The body is invalid in context — for example a missing required `name`/`watchlist-entries` or an entry without a `symbol`. Read `error.message` for the reason. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/watchlists", "method": "post", "operation": { "description": "Creates a new watchlist for the authenticated user. The body requires `name` and `watchlist-entries`; each entry requires a `symbol`, and `instrument-type` is optional.", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/postWatchlists" } } }, "required": true }, "responses": { "201": { "description": "The watchlist was created and is returned as stored.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Watchlist" }, "context": { "type": "string", "example": "/watchlists" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or account authority does not permit creating watchlists.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "422": { "description": "The body is invalid in context — for example a missing required `name`/`watchlist-entries` or an entry without a `symbol`. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "user-watchlists" ], "operationId": "postWatchlists", "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": false, "x-rate-limit-bucket": "write", "summary": "Create Watchlist" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # GET /watchlists/{watchlist_name} — Get Watchlist Returns a single watchlist belonging to the authenticated user, with its full `watchlist-entries`. URL-encode the name if it contains spaces (for example `Tech%20Megacaps`). **Group:** Watchlists · **operationId:** `getWatchlistsWatchlistName` ## Parameters - `watchlist_name` (path, required) — ## Responses - `200` — The requested user watchlist. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `404` — No watchlist exists with the given name for this user. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/watchlists/{watchlist_name}", "method": "get", "operation": { "description": "Returns a single watchlist belonging to the authenticated user, with its full `watchlist-entries`. URL-encode the name if it contains spaces (for example `Tech%20Megacaps`).", "parameters": [ { "in": "path", "name": "watchlist_name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The requested user watchlist.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Watchlist" }, "context": { "type": "string", "example": "/watchlists/{watchlist_name}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "404": { "description": "No watchlist exists with the given name for this user.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "user-watchlists" ], "operationId": "getWatchlistsWatchlistName", "x-tt-class": "read", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "read", "summary": "Get Watchlist" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # PUT /watchlists/{watchlist_name} — Replace Watchlist Replaces **all** properties of an existing user watchlist — this is a full replacement, not a merge, so send the complete `watchlist-entries` array you want to keep; omitted entries are removed. **Group:** Watchlists · **operationId:** `putWatchlistsWatchlistName` ## Parameters - `watchlist_name` (path, required) — ## Responses - `200` — The watchlist was replaced and the updated version is returned. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `403` — Authenticated, but the token's scope or account authority does not permit modifying this watchlist. - `404` — No watchlist exists with the given name for this user. - `422` — The body is invalid in context — for example a missing required `name`/`watchlist-entries` or an entry without a `symbol`. Read `error.message` for the reason. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/watchlists/{watchlist_name}", "method": "put", "operation": { "description": "Replaces **all** properties of an existing user watchlist — this is a full replacement, not a merge, so send the complete `watchlist-entries` array you want to keep; omitted entries are removed.", "parameters": [ { "in": "path", "name": "watchlist_name", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/putWatchlistsWatchlistName" } } }, "required": true }, "responses": { "200": { "description": "The watchlist was replaced and the updated version is returned.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Watchlist" }, "context": { "type": "string", "example": "/watchlists/{watchlist_name}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or account authority does not permit modifying this watchlist.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No watchlist exists with the given name for this user.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "422": { "description": "The body is invalid in context — for example a missing required `name`/`watchlist-entries` or an entry without a `symbol`. Read `error.message` for the reason.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "preflight_check_failure", "message": "One or more preflight checks failed", "errors": [ { "code": "preflight_check_failure", "message": "A specific validation failed for this order." } ] } } } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "user-watchlists" ], "operationId": "putWatchlistsWatchlistName", "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "write", "summary": "Replace Watchlist" } } ``` --- > Documentation index: fetch https://developer.tastytrade.com/llms.txt to discover all pages before exploring further. # DELETE /watchlists/{watchlist_name} — Delete Watchlist Permanently deletes the named user watchlist and returns the deleted watchlist in the response. **Group:** Watchlists · **operationId:** `deleteWatchlistsWatchlistName` ## Parameters - `watchlist_name` (path, required) — ## Responses - `200` — The watchlist was deleted and is returned as it existed before deletion. - `401` — Missing or invalid access token, or a missing/malformed `User-Agent` header. - `403` — Authenticated, but the token's scope or account authority does not permit deleting this watchlist. - `404` — No watchlist exists with the given name for this user. - `429` — Rate limit exceeded. Back off exponentially before retrying. # OpenAPI definition ```json { "openapi": "3.1.0", "path": "/watchlists/{watchlist_name}", "method": "delete", "operation": { "description": "Permanently deletes the named user watchlist and returns the deleted watchlist in the response.", "parameters": [ { "in": "path", "name": "watchlist_name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "The watchlist was deleted and is returned as it existed before deletion.", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Watchlist" }, "context": { "type": "string", "example": "/watchlists/{watchlist_name}" } }, "required": [ "data", "context" ] } } } }, "401": { "description": "Missing or invalid access token, or a missing/malformed `User-Agent` header.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "unauthorized", "message": "No valid access token was provided; access tokens expire after 15 minutes." } } } } } }, "403": { "description": "Authenticated, but the token's scope or account authority does not permit deleting this watchlist.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ], "example": { "error": { "code": "not_permitted", "message": "User not permitted access" } } } } } }, "404": { "description": "No watchlist exists with the given name for this user.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } }, "429": { "description": "Rate limit exceeded. Back off exponentially before retrying.", "content": { "application/json": { "schema": { "type": "object", "description": "Standard tastytrade error envelope. Branch on error.code, not the message text.", "properties": { "error": { "type": "object", "required": [ "code", "message" ], "properties": { "code": { "type": "string", "description": "Machine-readable error code (see the Error reference)." }, "message": { "type": "string", "description": "Human-readable explanation." }, "errors": { "type": "array", "description": "Present for multi-error / validation failures; one entry per problem.", "items": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "domain": { "type": "string" } } } } } } }, "required": [ "error" ] } } } } }, "tags": [ "user-watchlists" ], "operationId": "deleteWatchlistsWatchlistName", "x-tt-class": "mutating", "x-money-moving": false, "x-idempotent": true, "x-rate-limit-bucket": "write", "summary": "Delete Watchlist" } } ```