DEVELOPER GUIDE

Limits & pagination

Handle query costs, cursors, caching and plan capacities.

Plans and enforced limits

REST access is part of the same FilingSift research platform presented in the browser. Free, Builder, Professional, and Team differ on server-enforced monitored companies, concurrent onboarding, monthly API requests, monthly query-cost units and organization members—not on evidence or validation standards. All plans include all available indexed filing history for permitted companies, plus five active API keys and ten active sessions per user. Indexed history has no plan-based age cutoff; availability depends on indexed records. Onboarding and provider retrieval retain separate lookback and request limits. The plan fields indexedHistory, onboardingHistoryDays and referenceHistoryDays describe these separately. Legacy historyDays is a deprecated alias for the onboarding lookback, not a filing-read limit. These are hard limits, not overage pricing: a request or account action that exceeds a limit stops with a structured response and does not create an additional charge. Read GET /api/v1/billing/catalog for the live v2 contract and Plans & pricing for the buyer-facing comparison.

Query-cost units

Query-cost units bound request complexity; they are not money and are never billed as an overage. For REST requests that reach the query-cost guard, cost is 5 + effective limit + (3 × other query parameters) + (2 when a cursor is present). The cost guard reads URL query parameters, not JSON-body filters. The effective query-string limit defaults to 20 when omitted; limit and cursor are excluded from the “other query parameters” count. For example, a request with no query parameters costs 25 units, while ?limit=20&ticker=AAPL costs 28. For a JSON-body search with no URL parameters, the guard cost is therefore 25 units even if the body requests a different result limit; operation-specific body bounds still apply. Responses that reach this guard report X-Query-Cost and X-Max-Query-Cost; earlier validation or proxy errors may not. A request above the per-request maximum is refused with query_cost_exceeded; authenticated data requests also stop with HTTP 429 when the organization reaches its monthly request or query-cost allowance. Account, admin and billing routes are excluded from monthly request metering; short-term rate limits and permissions still apply. Authenticated requests are reserved before route handling, so a later refusal or empty result can still consume allowance. Anonymous requests have safety limits but do not consume an organization allowance. Public BIS routes bypass account metering.

Filtering, pagination, limits, and caching

OperationContinuation contract
Structured filing and comparison listsRead meta.pagination.hasMore and meta.pagination.nextCursor; send the cursor in the query string with unchanged filters. Cursors bind to the ordered collection identities and filter set; membership/order changes require a restart. This is not a frozen content snapshot.
Market search, market screens and historical catalogRead data.pagination. For market search/screens, send cursor in the JSON body with the same query/screen and filters; for the catalog, send it in the query string. The market index is not pinned across pages, and an empty page can still have more candidates.
Bounded search POST /search, financing screens and matrixNo cursor-based next page. Inspect the operation's bounds and truncation information, then narrow your selection when needed.

Check hasMore, not just whether this page has matches; use a request budget. Restart on invalid_cursor or invalid_search_cursor and deduplicate records already handled. Every operation has its own allowed filter names and limits.

Cacheable public JSON GET responses include strong ETags and can return HTTP 304 for a matching If-None-Match. Authenticated JSON responses and explicitly private/no-store routes are not shared-cacheable; this does not promise ETags for every download or provider route. Rate limits and response-size bounds still apply. Check Usage and the error envelope rather than assuming every HTTP 429 has the same reset time.

← Browse all documentation