Skip to content

Error Codes ​

One error model spans the SDK: the Rust core classifies every failure once, and each language surfaces the classification in its idiom. Catch the specific class you can recover from; let the rest propagate.

Download as CSV

ConditionRust Error variantPython exceptionC++ exception
Bad or expired credentialsAuthAuthenticationError / InvalidCredentialsErrorthetadatadx::AuthenticationError / thetadatadx::InvalidCredentialsError
Endpoint needs a higher tierGrpc (permission)SubscriptionErrorthetadatadx::SubscriptionError
Too many requests in flight upstreamGrpc (resource exhausted)RateLimitErrorthetadatadx::RateLimitError
Request returned no rowsGrpc (not found)NotFoundError / NoDataFoundErrorthetadatadx::NotFoundError
Per-request deadline elapsedTimeoutDeadlineExceededError / TimeoutErrorthetadatadx::DeadlineExceededError
Connection / TLS / protocol faultTransportNetworkErrorthetadatadx::NetworkError
Response shape unexpectedDecodeSchemaMismatchErrorthetadatadx::SchemaMismatchError
Streaming session faultStreamStreamErrorthetadatadx::StreamError
Invalid parameters / configurationConfigThetaDataErrorthetadatadx::ThetaDataError
  • Python exceptions all derive from ThetaDataError, so except ThetaDataError is the catch-all.
  • TypeScript throws a typed subclass, the same hierarchy the other bindings expose: catch (e) { if (e instanceof SubscriptionError) ... }. A rate-limit error carries retryAfter. The message still carries the same stable text as the Rust Display output, but an instance check is the reliable test, not a pattern over the message.
  • C++ exceptions derive from thetadatadx::ThetaDataError, so catch (const thetadatadx::ThetaDataError&) is the catch-all.
python
from thetadatadx import NoDataFoundError, RateLimitError, ThetaDataError

try:
    rows = client.market_data.option_history_trade("SPY", "20250321", "20250303", strike="570", right="C")
except NoDataFoundError:
    rows = []                # nothing traded — a normal outcome, not a failure
except RateLimitError:
    ...                      # back off and retry; see Concurrent Requests
except ThetaDataError:
    raise                    # anything else is a real failure

Transient faults (transport drops, upstream exhaustion) are retried inside the SDK with backoff before any error surfaces; tune the budget via the retry_* configuration fields.

Server errors ​

The HTTP server answers a failed data request the way the terminal does: with an HTTP status and the reason as a plain-text (text/plain) body.

HTTP statusMeaning
400Missing or invalid parameter; the body names it.
404Unknown endpoint; the body names it. A path the server does not serve at all gets an empty 404.
410A v2 query parameter; the body names its v3 replacement.
503Upstream capacity exhausted after retries; carries Retry-After.
Set by the upstreamThe upstream service rejected the request. The server answers with the HTTP status the service attaches to the rejection (for example its no-data status when a query matches no rows) and the service's description, or with 500 when the service attaches no status.

Three kinds of failure are answered with a JSON envelope instead, whose error_type names the class: a query string the server cannot accept (more than 32 parameters, or one it cannot parse), every failure on the flat-file routes, and an internal fault while the server renders a response.

json
{
    "header": { "error_type": "bad_request", "error_msg": "request has 40 query parameters; max is 32" },
    "response": []
}
HTTP statuserror_typeMeaning
400bad_requestThe query string or a flat-file parameter was rejected; the message names it.
404flatfiles_no_dataNo flat file is available to this account for the requested date.
502flatfiles_unavailableThe upstream failed while serving the flat file.
500serialization_error, server_errorThe server failed to render the response. This is a defect in the server, not a data condition.

Released under the Apache-2.0 License.