Errors & Troubleshooting
Troubleshooting

Errors & Troubleshooting

The WSO API returns structured JSON error responses with standard HTTP status codes, programmatic error codes, and descriptive messages.

Standard Error Envelope

Every non-2xx response returns an application/json error body following this schema:

json
{
  "error": "invalid_parameter",
  "message": "expiration must be in YYYY-MM-DD format",
  "status": 400,
  "timestamp": "2026-09-17T20:00:00Z",
  "request_id": "c7a9b1c0-4f2e-4d1a-8c3b-5e6f7a8b9c0d"
}

Error Codes Reference

Programmatic error codes returned by the API, generated directly from the OpenAPI specification error catalogue:

StatusError CodeDescription
403account_suspendedThis account cannot use the API right now. Contact us for details.
403endpoint_not_allowedThis endpoint is not available for your account.
503endpoint_unavailableThis endpoint is temporarily unavailable. Retry later.
503entitlement_unavailableAccount entitlement database or subscription cache is temporarily unreachable.
500internal_errorAn unexpected server error occurred while processing the request. Retry with exponential backoff.
403ip_blockedRequests from this network are not accepted. Contact us if you believe this is an error.
401invalid_authAuthorization header format is invalid. Must use the 'Bearer wso_live_...' scheme with a separating space.
400invalid_bodyRequest body is malformed JSON, unreadable, contains unrecognized fields, or exceeds 1 MiB.
401invalid_keyAPI key does not exist or was revoked. Generate a new key in the developer dashboard.
400invalid_pagePagination page parameter exceeds allowable bounds (e.g. page > 100).
400invalid_parameterQuery or path parameter failed format, type, or constraint validation (e.g. malformed symbol or bad limit).
400invalid_rangeNumerical or date range constraint violated (e.g. min exceeds max, or date range exceeds allowable span).
503maintenanceThe API is undergoing maintenance. Retry after the Retry-After interval.
405method_not_allowedHTTP method is not supported on this endpoint. Consult Allow response header.
401missing_authAuthorization header is missing or empty. Provide an API key via Bearer authentication.
400missing_symbolRequired equity symbol or option contract parameter was omitted.
400missing_symbolsRequired symbols parameter for batch request was omitted or empty.
404not_foundEndpoint route does not exist or requested option contract was not found in active chain records.
403origin_forbiddenRequest rejected because origin authentication failed. All requests must route through the configured Cloudflare edge proxy.
400out_of_rangeRequested date window exceeds retention horizon (e.g. 7-day flow retention) or market-wide window cap.
403plan_upgrade_requiredThe requested endpoint requires a higher tier plan than your current active plan. Response includes required_plan.
503query_timeoutDatabase execution budget exceeded for complex query or statement timeout. Retry with narrower parameters.
400query_too_broadMarket-wide query is insufficiently constrained; narrow search filters or specify symbol.
429rate_limitedAccount rate limit exceeded (or unauthenticated/public IP rate limit exceeded). Respect the Retry-After header before retrying.
503service_unavailableUnderlying market data cache, database, or verifier is temporarily unavailable.
403subscription_inactiveAccount subscription is inactive, unpaid, or canceled. Update payment methods in the dashboard.
403subscription_requiredAn active paid subscription plan is required to access data endpoints. Subscribe via the dashboard.
404symbol_not_foundUnderlying equity ticker symbol is unrecognized or has no options market data coverage.
429too_many_auth_failuresClient IP temporarily throttled due to repeated authentication failures.
429too_many_concurrent_requestsAccount in-flight concurrency ceiling exceeded. Reduce concurrent calls or wait for active requests to complete.
400too_many_filtersScreener request exceeds maximum permitted filter predicates count (up to 50 filters).
400too_many_symbolsBatch request exceeds maximum permitted symbols limit (up to 20 symbols).
403trial_endedYour trial has ended. Subscribe to keep using the API.
502upstream_errorUpstream market data provider returned an error and fallback stored data is unavailable.
403wrong_credential_typeA Firebase ID token or dashboard session credential was sent to /v1; use an API key (wso_live_...) instead. Legacy wsk_ keys return invalid_key (401).

Common Problems & Solutions

1. HTTP 401: Authentication Errors

Ensure your HTTP header contains Authorization: Bearer wso_live_.... Notice the space between Bearer and the key. Missing headers return missing_auth. Malformed headers return invalid_auth. Invalid or revoked keys (including legacy wsk_ keys) return invalid_key (401). If a Firebase ID token or dashboard credential is sent to /v1, the API returns wrong_credential_type (403).

2. HTTP 403: Forbidden Access & Plans

Data endpoints require an active plan or active trial. A key whose account has never had a plan gets HTTP 403 with code subscription_required; an account whose trial has expired receives trial_ended; an inactive or canceled plan returns subscription_inactive; and a request attempting to access endpoints outside your plan tier returns plan_upgrade_required. Direct requests bypassing the Cloudflare edge proxy return origin_forbidden. /v1/auth/verify and /v1/usage still answer with HTTP 200, so you can check your key status.

3. HTTP 429: Rate Limits & Backoff

Always inspect the Retry-After header on HTTP 429 responses. Wait the indicated number of seconds before retrying:

python
import time
import requests

def request_with_retry(url, headers, max_retries=3):
    for _ in range(max_retries):
        resp = requests.get(url, headers=headers)
        if resp.status_code == 429:
            retry_after = int(resp.headers.get("Retry-After", 1))
            print(f"Rate limited (429). Retrying in {retry_after}s...")
            time.sleep(retry_after)
            continue
        return resp
    raise Exception("Max retries exceeded")

4. HTTP 404: not_found vs symbol_not_found

The API returns not_found when an endpoint path doesn't exist or an individual option contract cannot be found. If the underlying equity ticker symbol itself is unknown or unsupported, the API returns symbol_not_found.

← Rate LimitsField Conventions →