POST /api/v2/filings/search to search filing documents or browse by metadata.
You need an API key with permission to view
SERFF filings. Readonly keys can use this operation.
Search document text
SetAPI_BASE to your API host (for example, https://canary.effectiveai.app) and
EFFECTIVE_API_KEY to your API key, then run:
filings array of filings, a nullable nextCursor, and an
exhaustive flag. Each filing includes its ID, source and native reference, company, state,
classifications and dates. By default, text results include matches from the
configured snippet mode. The optional textFetchMode uses the
values: docReader, fromTurbo, or none. Use none to skip text
hydration; document matches may still be returned without passages. Each match contains the
file ID, nullable version ID, name, and passages with available page numbers.
Missing metadata and page numbers are null. No matching filings returns an empty
filings array.
Filters combine with AND. Values within in and containsAny combine with
OR. Use the normalized toiCode, subToiCode, normalizedOutcome, and filingTypeNormalized
values defined in the API reference. Raw insurance classification labels and status
strings in the response may vary by source. Text/identifier queries default to
recent filings (2018+ and undated); metadata-only requests default to all dates.
Set dataScope explicitly to historical, recent, or all as needed.
Carrier filters use carrierIds (containsAny/notContainsAny) and canonical
naic:00123 IDs or numeric shorthand strings. Group equality uses groupId,
for example group:361. State values normalize to uppercase. Search’s
trackingNumber filters and sorts use backend reference spelling (including
FL- for IRFS); ordinary GET discovery accepts native source-qualified references.
A match’s versionId is currently null: the backend does not identify the exact
immutable bytes behind the evidence. Current downloads may differ from indexed
text. Do not treat today’s file version as the evidence version.
To match an exact phrase, quote it inside query, for example
"query": "\"roof exclusions\"". Exact phrases require a state, company,
NAIC, tracking-number or date filter to narrow the search. Exclusion filters alone
do not qualify. Without a narrowing filter, the shared search service removes the
quotes and performs keyword search.
Browse without document text
Omitquery to list filings by metadata alone. For example, replace the request
body above with:
sort to [{"field":"relevance","direction":"desc"}]. Browsing does not return snippets.
Tracking-number queries use the existing identifier lookup: complete identifiers
match exactly; partial identifiers use prefix matching with up to 10 results.
Metadata filters and data scope apply before the lookup result limit.
Metadata sorts use filing ID ascending as a final tie-breaker. Within text results,
missing values sort last; metadata-only sorting puts missing values first for descending sorts and last
for ascending sorts. Relevance retains backend
score order, including backend tie behavior. Neither ordering freezes membership.
Continue a search
WhennextCursor is non-null, repeat the same request with that value in cursor.
Keep the query, filters, data scope, sorting, text-fetch mode and page size unchanged.
Opaque server-held cursors bind the normalized query and caller scope and expire
24 hours after the first page; continuation never extends this lifetime. Tampered,
expired, or differently bound cursors return 400 invalid_cursor. Equivalent
explicit defaults and reordered set-valued filters continue successfully.
The private position is a live backend offset, not a saved search. Every page
reruns the query; index/ranking changes and concurrent edits may cause repeats or
omissions. Deduplicate IDs and restart when a fresh view is needed. Prefer GET
browsing for its keyset behavior when the simpler metadata filters suffice.
Text search returns a bounded candidate window, with exhaustive: false.
With textFetchMode: "docReader" or "fromTurbo", search retrieves at most
100 candidate documents. With "none" or an omitted mode, it requests up to 1,200.
An omitted mode uses the configured text-fetch strategy. Several documents can belong to one filing, so the number of filings
can be smaller. Metadata sorting applies within this window. A null cursor means
the available window is exhausted, and does not prove no more corpus matches exist.
Narrow your filters to investigate more specific results. No exact corpus total
is returned.
Metadata browsing returns exhaustive: true: pagination can traverse the matching
metadata records. This describes the available dataset, not completeness of every
state’s public filings or document indexing coverage.
Follow a result to bytes
Use IDs returned by search and the file inventory; never derive them from names.Handle errors
API-generated failures includeerror and code; responses are private and not
cacheable. JSON requests are limited to 64 KiB, reject unknown body/query fields,
and require application/json.
400 invalid_request: correct filters, dates, sorting or malformed JSON.400 invalid_cursor: restart with the original semantic request and no cursor.401 unauthenticated: check the API key.403 forbidden: the caller needs current Filing access within its credential scope.413 request_too_large/415 unsupported_media_type: correct the request body.503 temporarily_unavailable: respectRetry-After; narrow expensive queries before retrying timeouts. Cursor-store failure does not silently drop continuation.500 internal_error: unexpected failure; no backend details are exposed.