Skip to content
Cirrus home
Sign in

Guide

Errors, rate limits and retries

Every error code and what to do about it, the rate limits, and how Idempotency-Key makes retries safe.

Errors keep the usual envelope with error.code (stable, branch on it), error.message (plain English, show it) and error.field (the input at fault, when there is one).

{
  "status": "error",
  "data": null,
  "error": {
    "code": "invalid_request",
    "message": "price must be > 0 for LIMIT orders",
    "field": "orders[0].price"
  }
}
  • 4xx: the request was refused and nothing was done. Fix it before retrying.
  • 5xx: a problem on our side or at the broker. 503 means nothing was done: retry with backoff.
  • Quote the x-request-id response header when you ask for help.

Error codes #

CodeHTTPWhat it meansWhat to do
malformed_json400The body is not JSON, or does not fit the request shape (unknown or missing fields, wrong types).Fix the request as the message says. Retrying it unchanged fails again.
invalid_query400The query string does not fit the route's parameters.Fix the request as the message says. Retrying it unchanged fails again.
bad_request400The request could not be read before reaching the route (e.g. an unreadable path segment); message says what.Fix the request as the message says. Retrying it unchanged fails again.
idempotency_key_required400The Idempotency-Key header is missing (use a new UUID per order request).Add an Idempotency-Key header: a new UUID per request.
invalid_idempotency_key400The Idempotency-Key header is not 1-128 printable characters.Fix the request as the message says. Retrying it unchanged fails again.
unauthorized401No credential, or the credential is invalid, expired or revoked.Check the Authorization header. If the key was revoked, create a new one.
forbidden403The credential may not use this route (missing scope, app-session-only route, IP not allowed).Use a key with the scope named in the message, from an allowed IP. App-only routes need the app.
own_session_required403Credentials can only be created from the user's own signed-in session.Your credential may not do this. Check its scopes, IP allowlist or plan.
live_not_enabled403Live deployments need the strategies_live scope and a broker open for live automated strategies.Your credential may not do this. Check its scopes, IP allowlist or plan.
oms_not_enabled403Order management is not enabled for this user.API access is not on for your account yet. Ask support to enable it.
not_shared403That user has not shared this data with the caller.Your credential may not do this. Check its scopes, IP allowlist or plan.
account_not_found404No linked broker account with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
instrument_not_found404No instrument with this token (unknown or expired).Check the id: it may be wrong, gone, or belong to another account.
basket_not_found404No saved basket with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
watchlist_not_found404No watchlist with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
trigger_not_found404No trigger with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
api_key_not_found404No API key with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
connection_not_found404No connected partner app with this client id.Check the id: it may be wrong, gone, or belong to another account.
unknown_app404Unknown or disabled partner app.Check the id: it may be wrong, gone, or belong to another account.
endpoint_not_found404No signal URL with this id (or this secret) for the caller.Check the id: it may be wrong, gone, or belong to another account.
webhook_not_found404No webhook with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
telegram_not_linked404Telegram is not connected for the caller; start a link first.Check the id: it may be wrong, gone, or belong to another account.
activity_not_found404No activity record with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
strategy_not_found404No automated strategy with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
version_not_found404No such version of the strategy.Check the id: it may be wrong, gone, or belong to another account.
shared_not_found404Nothing is shared with the caller here: the share was stopped or the link revoked, or it never existed.Check the id: it may be wrong, gone, or belong to another account.
listing_not_found404No such gallery listing for the caller: withdrawn, taken down, not approved yet (and not theirs), or it never existed.Check the id: it may be wrong, gone, or belong to another account.
deployment_not_found404No deployment with this id for the caller.Check the id: it may be wrong, gone, or belong to another account.
backtest_not_found404No backtest with this id for the caller (results are kept 30 days).Check the id: it may be wrong, gone, or belong to another account.
schema_not_found404No such strategy document format on this server.Check the id: it may be wrong, gone, or belong to another account.
order_not_found404No order with this id (broker order id or order_tag) in the caller's order book today.Check the id: it may be wrong, gone, or belong to another account.
request_in_progress409A request with this Idempotency-Key is still being processed.Wait a moment, then retry with the same Idempotency-Key.
trigger_busy409The trigger changed while it was being updated; retry.It clashes with the current state. Read the latest state, then decide.
trigger_fired409The trigger already fired; its exit is being handled.It clashes with the current state. Read the latest state, then decide.
broker_held409The protection is held by the broker; change the broker order instead.It clashes with the current state. Read the latest state, then decide.
watchlist_name_taken409The caller already has a watchlist with this name.It clashes with the current state. Read the latest state, then decide.
webhook_limit_reached409The webhook limit is reached; delete one first.It clashes with the current state. Read the latest state, then decide.
conflict409A partner app's webhook was changed at the same time as this request; retry.It clashes with the current state. Read the latest state, then decide.
already_flat409There is no open position to exit for this account, instrument and product.It clashes with the current state. Read the latest state, then decide.
stale_quote422This order cannot be sent at market: there is no price for the instrument at all (a price that is not recent is used: the order goes out as a LIMIT protected from it), or the best bid / ask is too far from the last traded price (a thin book); the message says which. Place a LIMIT order instead. Nothing was sent to the broker.Fix the field named in error.field. Nothing was done.
bracket_position409The position is held by a bracket / cover order: exit it with DELETE /v1/orders/bracket/{order_id}, which squares it off at the broker. Nothing was placed.It clashes with the current state. Read the latest state, then decide.
position_protected409The order is a (partly) filled bracket / cover entry: cancelling it would cancel the live stop-loss / target legs of its position. Send legs=true to do it anyway.It clashes with the current state. Read the latest state, then decide.
order_not_open409The order is already finished (filled, cancelled or rejected), so there is nothing to modify or cancel. Nothing was sent to the broker.It clashes with the current state. Read the latest state, then decide.
ambiguous_order409The id names orders in more than one account (or several orders); message lists the accounts. Add account= to choose one.It clashes with the current state. Read the latest state, then decide.
strategy_busy409The strategy changed since it was read (or is archived); read it again and retry.It clashes with the current state. Read the latest state, then decide.
strategy_in_use409The strategy has a deployment that is not stopped; stop it first.It clashes with the current state. Read the latest state, then decide.
deployment_finished409The deployment is stopped; deploy the strategy again to run it.It clashes with the current state. Read the latest state, then decide.
deployment_limit_reached409The most deployments that may run at once are running; stop one first.It clashes with the current state. Read the latest state, then decide.
backtest_limit_reached409The most backtests that may be queued or running at once, or started today, are reached.It clashes with the current state. Read the latest state, then decide.
backtest_finished409The backtest has already finished (done, failed or cancelled); nothing to cancel.It clashes with the current state. Read the latest state, then decide.
no_saved_version409A strategy is shared as a saved version, never its draft: save a version first.It clashes with the current state. Read the latest state, then decide.
not_enough_cycles409A gallery listing needs at least 20 finished trades of the version in the author's runs with the chosen badge.It clashes with the current state. Read the latest state, then decide.
listing_pending409A listing of this strategy is already waiting for review; withdraw it first.It clashes with the current state. Read the latest state, then decide.
purchase_required409A paid gallery template must be bought before it is copied.It clashes with the current state. Read the latest state, then decide.
insufficient_credits409Not enough platform credits for this purchase; nothing was charged.It clashes with the current state. Read the latest state, then decide.
purchase_failed409A gallery purchase did not complete and nothing was charged; retry with a new Idempotency-Key.It clashes with the current state. Read the latest state, then decide.
purchase_in_progress409A gallery purchase with this Idempotency-Key is still being made; retry with the same key.It clashes with the current state. Read the latest state, then decide.
not_flat409A signal strategy's mode can change only when flat: a position held by the signal strategy, or an open trade on the deployment, must close first. Nothing was changed.It clashes with the current state. Read the latest state, then decide.
payload_too_large413The request body is larger than the server accepts; send less (e.g. fewer orders per request).Read the message; it says what went wrong.
invalid_request422The request is well-formed but not valid; field names the input.Fix the field named in error.field. Nothing was done.
invalid_document422The strategy document has problems; message lists each (where in the wizard, what is wrong) and field names the first.Fix the field named in error.field. Nothing was done.
not_deployable422The strategy version cannot be deployed yet (a component or option not released, or an underlying not open); message says why.Fix the field named in error.field. Nothing was done.
acknowledgement_required422A warning must be acknowledged to deploy (e.g. unlimited_loss): add its code to acknowledge.Fix the field named in error.field. Nothing was done.
idempotency_key_reused422This Idempotency-Key was already used with a different request.Send a new Idempotency-Key for a new request.
partial_lot_position422The open position (less exits already working) is not a whole number of lots, so it cannot be fully exited through this route; message says how much remains.Fix the field named in error.field. Nothing was done.
not_supported_by_broker422The account's broker does not offer this (e.g. margin calculation, GTT listing, or GTT on BFO / intraday at Pocketful).Fix the field named in error.field. Nothing was done.
gtt_refused422The broker refused the GTT protecting a position and rules.fallback is reject: nothing was created.Fix the field named in error.field. Nothing was done.
archive_day_too_large422That day's archived activity is too large to serve at once.Fix the field named in error.field. Nothing was done.
invalid_client422OAuth: unknown partner app, or wrong client credentials.Fix the field named in error.field. Nothing was done.
invalid_grant422OAuth: the authorization code or refresh token is invalid, used or expired.Fix the field named in error.field. Nothing was done.
unsupported_grant_type400OAuth token endpoint: grant_type is missing or not supported.Fix the request as the message says. Retrying it unchanged fails again.
slow_down429OAuth token endpoint: too many failed attempts from this source; retry after Retry-After.Slow down and retry later.
invalid_scope422OAuth: a requested scope is unknown or not allowed for the app.Fix the field named in error.field. Nothing was done.
temporarily_unavailable503OAuth: the authorization server is temporarily unavailable.Temporarily unavailable. Retry with backoff.
rate_limited429Too many requests for this credential (or too many failed attempts); retry after the Retry-After header (seconds; error.retry_after_ms has the exact wait).Wait as long as the message says, then retry. Spread requests out.
broker_refused502The broker refused the change.The broker failed. Nothing may have reached it: check, then retry.
broker_outcome_unknown504The broker did not answer in time: it may or may not have applied the change. Check before retrying.The broker did not answer in time. Check the order book before retrying, then retry with the same Idempotency-Key.
service_unavailable503A dependency is temporarily unavailable, or the feature is off on this server; retry later.Nothing was done. Retry with backoff (1 s, 2 s, 4 s …).
credits_unavailable503Platform credits can't be reached right now; nothing was charged. Retry.Temporarily unavailable. Retry with backoff.
instruments_unavailable503The instrument master is not loaded yet; retry shortly.Temporarily unavailable. Retry with backoff.
trigger_worker_down503No trigger exit worker is running; nothing was created.Temporarily unavailable. Retry with backoff.
webhooks_disabled503Webhooks are not enabled on this server.Temporarily unavailable. Retry with backoff.
notifications_disabled503Notifications are not enabled on this server.Temporarily unavailable. Retry with backoff.
unavailable503Stream only: live updates are unavailable; reconnect.Temporarily unavailable. Retry with backoff.

Rate limits #

Defaults shown; a deployment can change them.

  • Per API key: 20 requests a second by default. Over it, 429 rate_limited at once; the message says how many ms to wait.
  • Per partner app and user: the same budget, counted separately for each user who connected the app.
  • Failed credentials: after about 30 failures in a minute from one IP, that IP gets 429 until the minute is up.
  • Per broker account: orders, modifies, cancels, GTT and convert share one budget (10 a second by default). A burst waits up to 2 s for a slot instead of failing.
  • Portfolio reads come from snapshots and never spend the broker budget.
  • Signal webhook URLs each have their own limit (429 over it).

Safe retries: Idempotency-Key #

  • Required on POST /v1/orders and POST /v1/orders/bracket: 1-128 printable characters, a new UUID per request. Keys are per user.
  • A retry with the same key and the same body returns the original response unchanged (for 24 hours), with the header idempotent-replayed: true. Nothing is placed twice.
  • While the first request is still running a retry gets 409 request_in_progress; the same key with a different body gets 422 idempotency_key_reused.
  • After a timeout or a slice with status unknown, retry with the same key, never a new one.

In the reference