Skip to main content
Every error response from Portal uses one JSON envelope, on any endpoint and for any data source:
Two fields carry the meaning, and they answer different questions:
  • type is the coarse category. It is a closed set of four values. Branch on it.
  • code is the specific cause. Match on it when you handle one case.
message is prose for humans. It is not stable and is not part of the contract, so do not parse it or match on it. param appears when the error concerns one request parameter. request_id appears in the body on 5xx responses; the same id is sent on every response as the x-request-id header, so quote it when reporting a problem.
A 204 No Content response is not an error. It is the correct answer when the requested range has no blocks yet, and it carries no body, no type, and no code.

Error types

The split between the last two matters: availability_error means a later attempt can still work, while api_error means an invariant broke and a retry loop cannot help.

Error codes

Codes are added over time. Treat an unknown code according to its type. That is why the two axes exist: a client that branches on type keeps working when a new code appears.

Backing off

Retry-After is mandatory on every overloaded response and is always at least one second. Honor it:
For overloaded, the value is in seconds, never an HTTP date. When Portal proxies a capacity refusal from a data source, it forwards that source’s interval when usable and substitutes its own minimum otherwise. An upstream_unavailable response can also carry a Retry-After supplied by the data source. Honor it when present. Portal does not add or normalize this value itself.

Browser clients

Portal exposes Retry-After and x-request-id through CORS, together with the stream metadata headers x-sqd-data-source, x-sqd-head-number, x-sqd-finalized-head-number, and x-sqd-finalized-head-hash. The default Fetch response-header safelist contains none of them, so without this a browser client would see a status code and nothing else. JavaScript code can read all of these headers from a fetch response. For the 409 Conflict recovery procedure, continue with Blockchain forks. For the retry loop of a streaming client, see EVM stream continuation or Solana stream continuation.