sifting/io
Operations · REST

Errors & rate limits.

Every error code the SiftingIO REST API can return, the envelope shape, the rate-limit headers every response carries, and the per-plan REST and WebSocket limits by tier.

Error envelope

Every error response carries a JSON body with an error code and a human-readable message. HTTP status follows standard conventions; the error code (snake_case) is the stable machine-readable identifier you should switch on.

error envelope · application/json
{ "error": "error_code", "message": "human-readable details" }

Error codes

Switch on the snake_case error field. HTTP status maps loosely to category, the code is what stays stable.

  • 400(raw message)

    Malformed query, invalid cursor, bad limit, missing required parameter.

  • 401unauthorized

    API key missing or invalid.

  • 403(raw message)

    Authenticated but not entitled, your subscription doesn't include this product or market.

  • 404unknown_ticker

    :ticker not in the SEC's US ticker registry.

  • 404unknown_filer

    :filer (ticker or CIK) not found.

  • 404filing_not_found

    Specific accession isn't in this filer's recent-filings window.

  • 404no_13f_filings

    Filer has never filed 13F-HR.

  • 404not_found

    Concept / period / unit combination has no data, or symbol absent from live feed.

  • 404section_not_found

    Requested filing section couldn't be extracted, body includes `available` (sections that were extracted).

  • 404insufficient_filings

    Risk-factors diff needs ≥ 2 10-Ks; this filer has fewer on record.

  • 400invalid_section

    :section not in the allowed list, body includes `valid_options`.

  • 400invalid_accession_format

    Accession number didn't match the dashed/undashed shape.

  • 400invalid_date_range

    Economic calendar: `to` must be strictly after `from`, range capped at 365 days.

  • 406gzip_required

    Heavy endpoint called without Accept-Encoding: gzip.

  • 422risk_factors_unavailable

    Item 1A couldn't be extracted from one or both 10-K filings being diffed.

  • 422insufficient_history

    Not enough bars to compute a technical signal for the requested symbol and interval.

  • 429rate_limit_exceeded

    Per-tier rate budget exhausted, inspect Retry-After.

  • 502upstream_error

    Filings source returned a non-success status. Retry shortly.

  • 502malformed_upstream

    Filings source returned an invalid payload, or live snapshot couldn't be parsed.

  • 503stale_snapshot

    Live snapshot older than the configured threshold (default 5s). Body carries last_t and server_now.

  • 503upstream_rate_limited

    Filings source throttled our pipeline. Retry shortly.

Rate-limit headers

Every REST response carries these. Read them to self-throttle before you hit a 429.

  • X-RateLimit-Limit

    Token bucket burst capacity for your subscription tier.

  • X-RateLimit-Remaining

    Tokens remaining in the current window.

  • Retry-After

    Seconds to wait before retrying. Sent on 429 responses.

Limits by plan

What the headers above are measured against. These are the headline REST and WebSocket limits for every market at each tier. The full feature comparison and per-market prices live on the pricing page.

PlanREST monthly quotaRate limitWS connectionsWS subscriptions
Free10,000 calls/mo60 req/min15
Builder250,000 calls/mo100 req/sec3100
Pro5,000,000 calls/mo150 req/sec101,000
UltraUnlimited calls250 req/sec (upgradeable)50Unlimited
EnterpriseCustomCustomCustomCustom

Two independent limits

Every plan carries a monthly call quota (the headline metric) and a per-second rate limit (a fairness floor so one client can't overwhelm the service during volatile markets). Most workloads only ever touch the monthly quota.

Per market, per tier

Limits apply to each market you subscribe to, at that market's tier. Run Stocks on Pro and Crypto on Builder and each enforces its own tier's limits, independently, on one account.

When the monthly quota runs out

On Free and Builder, calls past the quota return 429 with Retry-After until the next billing cycle: a hard cap and a predictable bill. On Pro you can opt in to soft overage at a transparent per-call rate. Enterprise negotiates overage and committed throughput. We never silently bill or degrade.

When you hit the rate limit

Requests past the per-second rate limit return 429. Back off using the Retry-After header and the X-RateLimit values above to self-throttle before you get there. In practice most clients never reach it.

Raising a limit without upgrading

Top up REST quota in 1M-call packs, lift the rate limit in +200 req/sec increments on Pro and Ultra, or add WebSocket capacity, all as add-ons. See the pricing page for details.

Plan budgets

The per-plan limits above apply per market. The pricing page has the full feature comparison, per-market prices, and add-ons. Upgrades raise your quota and rate limit without changing the headers or codes.