Developers menu
Developers / Errors
Markdown copyErrors
Branch on the status first, then on code. Retry only what the table marks retry: a 429 after Retry-After, a 5xx with backoff. Everything else needs a change on your side.
The shape
| Products | Body | |
|---|---|---|
| LIVE, ORDERS | { "error": { "code": "<code>", "message": "<words>" } } | The levels API, the Orders API and the POSITIONS API. Extra fields ride beside code where a table names them (retry_after_s, oldest, pricing, live). |
| LAB | { "error": "<words>" } | The LAB API answers with the status and a sentence; extra fields beside it (buy, holder, refunded). |
| GEO | { "error": "<words>" } | The Geo API, the same way. |
The levels API's levels answers 200 for the whole call; a symbol that fails carries its own error object (unknown_symbol, no_data, no_basis, contract_not_live) and the others still answer.
A platform that cannot read an HTTP status adds errors=200 to a levels API call: an error then answers 200 with the same body and the real status in X-FirmTape-Status.
Every code
| Status | Code | Retry? | Products | Meaning | What to do |
|---|---|---|---|---|---|
| 400 | missing_sym | no | LIVE | No sym was given. | Pass sym, one symbol or a comma list. |
| 400 | too_many_symbols | no | LIVE | More symbols than the call takes (20 a levels call, 8 a levels string). | Split the list over two calls. |
| 400 | bad_book | no | LIVE | book is not vol or oi. | Send book=vol or book=oi. |
| 400 | bad_g | no | LIVE | g is not a whole number from 0 to 30. | Send g between 0 and 30. |
| 400 | bad_day | no | LIVE, ORDERS | day is not YYYY-MM-DD. | Send the ET trading day as YYYY-MM-DD. |
| 400 | bad_time | no | LIVE, ORDERS | time (levels API, 09:31 to 15:59) or t (POSITIONS) is not an ET minute HH:MM of the session. | Send a minute of the session. |
| 400 | not_finished | no | LIVE | A past session was asked for with today's date or later. | Leave day out for today. |
| 400 | spx_only | no | LIVE | The expected move is measured for SPX only. | Send sym=SPX or leave it out. |
| 400 | bad_json | no | ORDERS | The body is not JSON. | Send Content-Type: application/json and a JSON object. |
| 400 | bad_op | no | ORDERS | op is not add, update or remove. | Send one of the three. |
| 400 | invalid | no | ORDERS | The position cannot be checked as sent; message says what to fix, in words. | Correct the field the message names. |
| 401 | no_key | no | LIVE, ORDERS | No key was sent (Orders: no key, or one that is unknown or revoked). | Send Authorization: Bearer <key> with a key of the product's scope. |
| 401 | bad_key | no | LIVE | The key is unknown or revoked. | Make a new key on Account, Integrations. |
| 403 | live_required | no | LIVE | The key is real; its account holds no active LIVE plan. | Start or renew LIVE; pricing names the page. |
| 403 | history_too_old | no | LIVE | The day is older than 90 days and the account holds no DATASET licence. | Ask for a day from oldest on, or add the DATASET licence. |
| 403 | plan | no | ORDERS | The key is real; the account is not on the Orders API or Team plan. | Move to the Orders API or Team plan. |
| 404 | not_found | no | LIVE, ORDERS | No such endpoint (levels API), or no position with this id on this account (POSITIONS). | Check the path or the id. |
| 404 | no_route | no | ORDERS | No such endpoint under /orders/api. | Use day, latest or sessions. |
| 404 | unknown_symbol | no | LIVE | FirmTape has no book for that symbol. | Pick one from GET /api/v1/symbols. |
| 404 | no_data | yes | LIVE | No reading for that symbol or day yet (before the first book of a session, or a day not in the archive). | Ask again after next_update_s, or pick another day. |
| 404 | no_basis | yes | LIVE | No ES, NQ or RTY basis measured for that day yet; the index levels exist, the offset does not. | Ask the index (SPX, NDX, RUT) or wait for the first basis pass. |
| 404 | contract_not_live | no | LIVE | That dated futures contract is not measured that day; live lists the ones that are. | Ask the front contract or one named in live. |
| 405 | method_not_allowed | no | LIVE | The levels API answers GET and HEAD only. | Send a GET. |
| 405 | method | no | ORDERS | The POSITIONS API takes GET or POST. | Send a GET or a POST. |
| 429 | rate_limited | yes | LIVE | More than 120 requests in a minute on one key. | Wait Retry-After seconds; poll with If-None-Match, a 304 is free. |
| 429 | too_many_places | no | LIVE | A live key answered from 3 client addresses this hour; a fourth is refused while the others keep working. | Make one key per machine. |
| 429 | rate | yes | ORDERS | The account's calls for the day are spent. | Wait for midnight ET, when the count resets. |
| 500 | internal | yes | LIVE | An error on FirmTape's side. | Retry with backoff; write to support if it lasts. |
| 503 | yes | LIVE | The account store did not answer while the key was checked. | Retry shortly. | |
| 401 | no | LAB | No key, or an unknown or revoked one. | Send a lab key. | |
| 402 | no | LAB | No credits: {"error": "no credits", "buy": "lab"}. Developing an idea also needs a positive balance. | Buy credits on the LAB page. | |
| 404 | no | LAB | No such idea or job, or not this account's. | Check the id. | |
| 409 | no | LAB | Another idea holds the conveyor (holder names it), or a step came out of order. | Finish or drop the holder; run the steps in order. | |
| 422 | no | LAB | The rule could not be compiled or the engine refused it (the credit is refunded). | Change the rule. | |
| 502 | yes | LAB | The engine failed (the credit is refunded). | Retry. | |
| 400 | no | GEO | A parameter is wrong; no call is counted. | Fix the parameter error names. | |
| 401 | no | GEO | No key, an unknown key or a revoked one. | Send a geo key. | |
| 403 | no | GEO | No active Geo API or Team plan, or a key beyond the plan's key count. | Check the plan on the account page. | |
| 429 | yes | GEO | The month's calls are used. | Wait for Retry-After, the start of the next UTC month. |
The single error envelope for every API is planned.
Measurements of dealer positioning, never a forecast or a trade call. This page is built from FirmTape's public contract, the same files the OpenAPI document is built from; the tests hold them against the route code. Markdown: /docs/developers/errors.md.