400, 401, 403, 404, 413 and 415 responses. A body-size refusal is JSON too, never a separate text format. Use the error-code reference for the complete declared list of codes and source reasons; the tables below group common refusals by what you are doing.
The examples come from one script, samples/http/errors.sh. It provokes three refusals and places no order.
The API may change until launch. Every change is listed in the Changelog.
Read a refusal
details.value names the value that was refused, such as an unknown asset id. details.reason carries a token that says why, for example on REQUOTE_REFUSED. details.retryAfter says how long to wait.
Here the script asks for a quote on an asset TetraFi does not list, prints the refusal and acts on its code:
Output
What next tells you
A refusal that you can recover from in a known way carriesnext. Its kind is the same set of steps a quote’s own next uses:
More kinds can be added. Treat a
kind you do not recognise as a step you cannot take automatically: show message and stop.
Retries
Whether to retry depends on the code, and for a code you do not know, on the status class.Waits
A refusal that names a wait carries it twice:- the
Retry-Afterheader, in whole seconds; details.retryAfter, an ISO 8601 duration such asPT3S. It can carry a fraction, such asPT1.5S.
The quote rate limit
You can send one live quote request every 3 seconds per API key. A requote counts as a quote request. A request answered entirely from cached prices does not count. A faster request answers429 QUOTE_RATE_LIMITED.
The script sends two quote requests at once, so one of them is refused. It waits details.retryAfter, then sends the refused one again:
Output
Orders
POST /api/v1/orders is safe to retry only with the same Idempotency-Key and the same body: the retry returns the first answer and never places a second order. When you do not know whether an order was placed (a timeout, a dropped connection, a 5xx), never send it again with a new key. Retry with the same key, or read the order by its quote first. Idempotency has the full rules.
Codes you do not know
New codes can be added at any time. Act on the codes you know, and treat any other by its status class, as the compatibility policy says: retry a429 or 503 after Retry-After, fix the request on any other 4xx, and retry a 5xx with backoff. Show message and log requestId either way.
The wrong workspace
An API key is bound to its workspace, so it may leaveX-Workspace-Id out. When it sends one, it must be the key’s own: any other workspace answers 403 WORKSPACE_SCOPE_MISMATCH, and a value that is not a workspace id answers 400 INVALID_WORKSPACE_ID. A signed-in member’s session must always send the header, or it is refused with 400 MISSING_WORKSPACE.
A few paths name a workspace, such as GET /api/v1/workspaces/{workspaceId}/webhooks. A path workspace that is not yours answers 404 WORKSPACE_NOT_FOUND, exactly as one that does not exist.
A workspace that cannot trade yet
A company, broker or liquidity provider workspace can request quotes, place orders and connect to counterparties once its company details are on file: legal name, country of incorporation, registration number and registered address. Until then, those requests answer403 CAPABILITY_BLOCKED. Each entry in details.capabilityBlockers names one thing to fix:
Refusal
Both are done in the app, not through the API. When TetraFi cannot read the company details just now, the request answers
503 CAPABILITY_UNAVAILABLE with the blocker BASE_PROFILE_UNREADABLE: send it again shortly. Treat a blocker code you do not recognise by its message and unlockStep.
To check before you quote, read GET /api/v1/workspaces/{workspaceId}/capabilities: each capability, such as request_quotes or submit_order, says whether it is allowed, with the same blockers when it is not.
Refusals by area
Each table lists the codes you can get from that part of the API with an API key. Unless a row says otherwise, nothing was placed or sent.Authentication and workspace
These can answer any request. Authentication explains keys, permissions and signing.
Every authentication failure is the one code
401 AUTH_REQUIRED. Its details.reason names the cause:
More reasons may be added: treat one you do not recognise as “fix the credentials”.
Quote request
POST /api/v1/quotes for a new search, and GET /api/v1/quotes/requests/{quoteRequestId} to read a quote set again. How search works covers the request.
A venue that cannot quote is not a refusal: the request succeeds and lists that venue in
sources with its outcome (below).
Requote
POST /api/v1/quotes with requote. Requotes and expiry covers the request.
Orders
POST /api/v1/orders and the order reads. Orders covers the request.
Idempotency
TheIdempotency-Key on POST /api/v1/orders, and GET /api/v1/orders/by-quote/{quoteId}. Idempotency has the full rules.
Prices and assets
GET /api/v1/prices, GET /api/v1/prices/stream and GET /api/v1/assets. Prices covers the request.
Source outcomes
A quote request that succeeds lists every venue it considered insources, each with a status and, when it did not quote, a reason. These are outcomes, not refusals: the request worked, and the venue’s line says why it gave no quote.
Some reasons you may see:
Both lists are open. New statuses and reasons appear without notice. Reasons are camelCase tokens. Treat a status or reason you do not know as a source you cannot use: show its
detail if you show anything, and carry on with the quotes you have.