[
  {
    "code": "400",
    "httpStatus": "400",
    "title": "Bad Request",
    "causes": [
      "Malformed JSON, or a body that doesn't match the endpoint schema.",
      "Missing required fields, or wrong types/param names (keys are dasherized)."
    ],
    "remediation": "Validate the request against the endpoint's schema in the API Reference. Ensure valid JSON and dasherized keys.",
    "docUrl": "/reference/errors#400"
  },
  {
    "code": "401",
    "httpStatus": "401",
    "title": "Unauthorized",
    "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."
    ],
    "remediation": "Send a valid `Authorization: Bearer <token>` (refresh every 15 minutes) AND always set a `User-Agent` like `my-app/1.0`.",
    "docUrl": "/reference/errors#401"
  },
  {
    "code": "403",
    "httpStatus": "403",
    "title": "Forbidden",
    "causes": [
      "Authenticated, but the token's scope or the account authority doesn't permit this action."
    ],
    "remediation": "Check your OAuth scopes and the account's authority level for the operation.",
    "docUrl": "/reference/errors#403"
  },
  {
    "code": "404",
    "httpStatus": "404",
    "title": "Not Found",
    "causes": [
      "Unknown resource — wrong account number, symbol, or order id.",
      "Wrong base URL / environment (sandbox vs production)."
    ],
    "remediation": "Verify the path and identifiers, and confirm the environment: sandbox `api.cert.tastyworks.com` vs production `api.tastyworks.com`.",
    "docUrl": "/reference/errors#404"
  },
  {
    "code": "422",
    "httpStatus": "422",
    "title": "Unprocessable Entity",
    "causes": [
      "The action is invalid in context. For orders, a rejection returns 422 with a reason in the response JSON's `error.message`."
    ],
    "remediation": "Read `error.message`. For orders, run the dry-run first and fix the rejection reason before submitting.",
    "docUrl": "/reference/errors#422"
  },
  {
    "code": "429",
    "httpStatus": "429",
    "title": "Too Many Requests",
    "causes": [
      "Request rate exceeded reasonable thresholds."
    ],
    "remediation": "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.",
    "docUrl": "/reference/errors#429"
  },
  {
    "code": "500",
    "httpStatus": "5xx",
    "title": "Server Error",
    "causes": [
      "An unexpected error on tastytrade's side."
    ],
    "remediation": "Retry with exponential backoff. If it persists, contact api.support@tastytrade.com with the request details.",
    "docUrl": "/reference/errors#500"
  },
  {
    "code": "unauthorized",
    "httpStatus": "401",
    "title": "`unauthorized`",
    "causes": [
      "No valid access token. Access tokens last 15 minutes and must be sent on every request."
    ],
    "remediation": "Generate an access token and include it in the `Authorization` header on every request.",
    "docUrl": "/reference/errors#unauthorized"
  },
  {
    "code": "invalid_credentials",
    "httpStatus": "401",
    "title": "`invalid_credentials`",
    "causes": [
      "Wrong username/password at login — often caused by using sandbox credentials against production (or vice versa); each environment has separate credentials."
    ],
    "remediation": "Confirm you're using the correct credentials for the environment you're hitting (sandbox vs production).",
    "docUrl": "/reference/errors#invalid_credentials"
  },
  {
    "code": "unconfirmed_user",
    "httpStatus": "401",
    "title": "`unconfirmed_user`",
    "causes": [
      "The user account has not completed confirmation/onboarding."
    ],
    "remediation": "Ensure the (sandbox) customer/account is fully created and confirmed. See the FAQ, or contact api.support@tastytrade.com.",
    "docUrl": "/reference/errors#unconfirmed_user"
  },
  {
    "code": "not_permitted",
    "httpStatus": "403",
    "title": "`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`."
    ],
    "remediation": "Verify the account number belongs to the authenticated user and that your credentials permit the operation.",
    "docUrl": "/reference/errors#not_permitted"
  },
  {
    "code": "preflight_check_failure",
    "httpStatus": "422",
    "title": "`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`)."
    ],
    "remediation": "Read each entry in `error.errors[]` and fix the order accordingly. Run the dry-run endpoint first to catch rejections before submitting.",
    "docUrl": "/reference/errors#preflight_check_failure"
  },
  {
    "code": "cannot_update_order",
    "httpStatus": "422",
    "title": "`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`."
    ],
    "remediation": "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.",
    "docUrl": "/reference/errors#cannot_update_order"
  },
  {
    "code": "cant_buy_for_credit",
    "httpStatus": "422",
    "title": "`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`."
    ],
    "remediation": "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.",
    "docUrl": "/reference/errors#cant_buy_for_credit"
  }
]