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).
- Back off exponentially on
429/5xx/network errors — see Rate limits & 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
- Generate a unique
external-identifierfor the order you intend to place. - Dry-run the order; only proceed if it returns no errors.
- Submit the order with your
external-identifierin the request body. - If you get a clear success or a clear rejection — you're done.
- If the response is uncertain (timeout, network drop,
5xx): do not blindly resubmit. First query your orders —GET /accounts/{account_number}/orders(or/accounts/{account_number}/orders/live; see /reference/orders) — and check whether an order with yourexternal-identifieralready 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) |
429 | Yes, after backoff — Rate limits & 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, 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.