API Reference / Errors
Error reference
Errors return an error object with code and message. Branch on the code, not the message text, and back off on 429.
docUrl convention: every entry below has a stable anchor, so an error maps to a fixed documentation URL — /reference/errors#<code> (e.g. /reference/errors#401). Agents can construct it from an error's HTTP status or error.code to self-correct. A machine-readable list is at /errors.json.
Bad Request
Common 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
Common 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 `<product>/<version>`; otherwise it returns 401.
Fix: Send a valid `Authorization: Bearer <token>` (refresh every 15 minutes) AND always set a `User-Agent` like `my-app/1.0`.
Forbidden
Common 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
Common 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
Common 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
Common 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 ErrorHTTP 5xx
Common 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
Common 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
Common 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
Common 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
Common 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
Common 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
Common 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
Common 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.