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.
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.
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": "error_code", "message": "human-readable details" }Switch on the snake_case error field. HTTP status maps loosely to category, the code is what stays stable.
(raw message)Malformed query, invalid cursor, bad limit, missing required parameter.
unauthorizedAPI key missing or invalid.
(raw message)Authenticated but not entitled, your subscription doesn't include this product or market.
unknown_ticker:ticker not in the SEC's US ticker registry.
unknown_filer:filer (ticker or CIK) not found.
filing_not_foundSpecific accession isn't in this filer's recent-filings window.
no_13f_filingsFiler has never filed 13F-HR.
not_foundConcept / period / unit combination has no data, or symbol absent from live feed.
section_not_foundRequested filing section couldn't be extracted, body includes `available` (sections that were extracted).
insufficient_filingsRisk-factors diff needs ≥ 2 10-Ks; this filer has fewer on record.
invalid_section:section not in the allowed list, body includes `valid_options`.
invalid_accession_formatAccession number didn't match the dashed/undashed shape.
invalid_date_rangeEconomic calendar: `to` must be strictly after `from`, range capped at 365 days.
gzip_requiredHeavy endpoint called without Accept-Encoding: gzip.
risk_factors_unavailableItem 1A couldn't be extracted from one or both 10-K filings being diffed.
insufficient_historyNot enough bars to compute a technical signal for the requested symbol and interval.
rate_limit_exceededPer-tier rate budget exhausted, inspect Retry-After.
upstream_errorFilings source returned a non-success status. Retry shortly.
malformed_upstreamFilings source returned an invalid payload, or live snapshot couldn't be parsed.
stale_snapshotLive snapshot older than the configured threshold (default 5s). Body carries last_t and server_now.
upstream_rate_limitedFilings source throttled our pipeline. Retry shortly.
Every REST response carries these. Read them to self-throttle before you hit a 429.
X-RateLimit-LimitToken bucket burst capacity for your subscription tier.
X-RateLimit-RemainingTokens remaining in the current window.
Retry-AfterSeconds to wait before retrying. Sent on 429 responses.
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.
| Plan | REST monthly quota | Rate limit | WS connections | WS subscriptions |
|---|---|---|---|---|
| Free | 10,000 calls/mo | 60 req/min | 1 | 5 |
| Builder | 250,000 calls/mo | 100 req/sec | 3 | 100 |
| Pro | 5,000,000 calls/mo | 150 req/sec | 10 | 1,000 |
| Ultra | Unlimited calls | 250 req/sec (upgradeable) | 50 | Unlimited |
| Enterprise | Custom | Custom | Custom | Custom |
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.
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.
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.
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.
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.
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.