/api/v1/sec/filingsList filings with pagination and filtering.
List filings with pagination and filtering. When querying by a single ticker, if no local filings exist yet, the API automatically backfills the complete filing history from SEC EDGAR (first call may take a few seconds). Pass a COMMA-LIST in `cik=` or `ticker=` (up to 100 entities) to fetch the merged most-recent filings across a whole watchlist in one call — the same `form_type`/`items`/`from_date`/`to_date` filters apply to the set, results are the latest across all of them (newest first, interleaved), and any entity with no ingested filings is listed in `meta.not_ingested[]`. A comma-list reads already-ingested rows only and never triggers an inline backfill.
Why use this
Common use case
Canonical chronological filings list — paginated, filterable by ticker / CIK / form_type / date-range, and self-healing on first-touch (auto-backfills the full submissions history from SEC EDGAR when no local data exists for a queried ticker). The first call for a fresh ticker may take a few seconds while the auto-backfill runs; subsequent calls hit the local index instantly. Use this as the entry point for any filing-timeline workflow, then drill into a specific filing with GET /api/v1/sec/filings/{accession_number} to fetch the full document URL set, or with GET /api/v1/sec/filings/{accession_number}/html for the primary document body. For aggregate counts use GET /api/v1/sec/filings/stats; for full-text search across filing bodies use POST /api/v1/scrapping/search/. 13F-specific holdings are surfaced separately via GET /api/v1/13f/filer/{cik}/holdings.
Parameters
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| ticker | query | optional | — | — | One ticker, or a COMMA-LIST of up to 100 tickers, each resolved to its CIK. A single ticker triggers auto-backfill from SEC EDGAR if no local data exists; a comma-list returns the merged most-recent filings ACROSS the set (newest first, interleaved) from already-ingested rows only and does NOT backfill. Tickers that resolve to no CIK are returned in meta.not_ingested[]. | AAPL,MSFT,TSLA |
| cik | query | optional | — | — | One CIK, or a COMMA-LIST of up to 100 CIKs. A comma-list returns the merged most-recent filings ACROSS the whole set (newest first, interleaved — not grouped by issuer), from already-ingested filings only. Combine with form_type/items/from_date/to_date to narrow. CIKs that have no ingested filings yet are returned in meta.not_ingested[] (a list never triggers an inline EDGAR backfill). | 320193,789019,1318605 |
| form_type | query | optional | — | — | Filter by Form Type (10-K, 4, 8-K) | 4 |
| items | query | optional | — | — | Filter by EDGAR 8-K item code(s). Single code (e.g. `2.02` = Results of Operations / earnings) or a comma-separated list for an OR-match (e.g. `2.02,9.01`) — returns filings whose `items` array contains ANY of the given codes. Each code must be N.NN (e.g. 1.01, 2.02, 5.02, 8.01); invalid codes return 400. Most useful with form_type=8-K (only 8-K-family forms carry item codes). | 2.02 |
| from_date | query | optional | — | — | Start Date (YYYY-MM-DD) | 2026-01-01 |
| to_date | query | optional | — | — | End Date (YYYY-MM-DD) | 2026-04-01 |
| sort | query | optional | filed_date:desc | — | Sort order. Format: field:direction. Fields: filed_date, updated_at. Directions: asc, desc. Shorthand 'asc'/'desc' also accepted (defaults to filed_date). Examples: sort=desc, sort=filed_date:asc | filed_at |
| limit | query | optional | 50 | — | Max 500 records | 20 |
| offset | query | optional | 0 | — | Pagination offset | 0 |
| include_total | query | optional | true | — | When `false`, skip the exact `COUNT(*)` (`meta.pagination.total` comes back `null`) and rely on `meta.pagination.has_more` for end-of-iteration. The exact count over a broad filtered set (e.g. `items=2.02` → ~200k matched rows) is a heap scan of every match and dominates latency; pass `include_total=false` for offset / infinite-scroll feeds that only need a page + "is there more". `has_more` stays exact (computed from a limit+1 fetch). Default `true` = exact count, unchanged. cik/ticker-scoped queries are always counted (cheap). | false |
| exhibits | query | optional | — | — | Filter by EDGAR exhibit / document type. `EX-99` (family) matches any EX-99.x; `EX-99.1` matches that exact type. Comma-separated for an OR-match (e.g. `EX-99.1,EX-99.2`); `exhibit` (singular) is an alias. Combine with `form_type=8-K&items=2.02` for a financial earnings release — an 8-K disclosing Item 2.02 with an Exhibit 99 press release (the widely-used commercial SEC-data earnings pattern). Tokens are upper-cased; invalid tokens return 400. Backed by `data[].exhibit_types`, populated as filings are enriched / backfilled. | EX-99 |
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| status | string | no | Always `"success"` on 2xx. ApiResponse envelope marker — present on every endpoint that wraps via `ApiResponse.paginated()`. Use to assert the call succeeded before reading `data`. |
| request_id | string | yes | Per-request UUID generated server-side. Surface this in support tickets — operations can grep it directly out of nginx + main_api logs to trace the exact request lifecycle (gateway routing, auth resolution, token debit, response). |
| timestamp | string | no | ISO-8601 UTC timestamp the response was generated server-side (suffix `Z`). Use as the freshness marker — auto-backfill calls that take a few seconds will surface here as a measurable lag from your client-side `Date.now()`. |
| data | array | no | Array of filing rows matching the query, sorted by `filed_date DESC` by default (newest first; configurable via `sort` param). Empty array when no rows match — never null. One element per filing — see `data[].*` for shape. |
| data[].id | integer | no | Internal `sec_filing_entries.id` row ID (auto-increment primary key). Stable across calls but not portable across environments — always join via `accession_number` for cross-environment work. |
| data[].accession_number | string | no | SEC accession number in the canonical 18-char dashed format `XXXXXXXXXX-YY-NNNNNN` (e.g. `0000320193-25-000123`). Globally unique across EDGAR; the natural primary key for any filing. Pass this to `GET /api/v1/sec/filings/{accession_number}` to retrieve metadata and document URLs. |
| data[].ticker | string | yes | Resolved ticker from the filer CIK via the `ticker_norm_aliases` lookup. Null when the filer has no public-equity ticker (private funds, individuals filing Form 4, foreign issuers without ADRs, dissolved entities). Multi-class issuers return the primary share class (e.g. BRK-A for Berkshire Hathaway). |
| data[].form_type | string | no | Canonical SEC form type as filed (e.g. `10-K`, `10-Q`, `8-K`, `4`, `13F-HR`, `13F-NT`, `13D`, `13G`, `S-1`, `20-F`, `144`, `DEF 14A`). Amendment variants append `/A` (e.g. `13D/A`, `10-K/A`). NT-prefixed and -NT-suffixed forms (`NT 10-K`, `13F-NT`) appear verbatim — these have no information table to drill into. Reference [SEC EDGAR form types](https://www.sec.gov/forms) for the full catalog. |
| data[].cik | string | yes | Filer CIK as a zero-padded 10-character string (e.g. `0000320193` for Apple). Note: SEC EDGAR's submissions API returns the unpadded form; FinRadar normalizes to 10-char padded form everywhere. Stable across decades — same CIK refers to the same legal entity. |
| data[].entity_name | string | yes | Filer's legal entity name as registered with SEC (e.g. `Apple Inc.`, `BERKSHIRE HATHAWAY INC`). Casing is whatever EDGAR provides — typically uppercase for institutional filers, mixed-case for issuers. For display, prefer the `company_name` alias which is the same value. |
| data[].company_name | string | yes | Frontend-friendly alias of `entity_name`. Same value, kept for backwards compatibility with older client code that queried `company_name`. |
| data[].role | string | yes | Role of the filer in this filing — relevant for insider filings (Form 4) and institutional filings (13F). Null for issuer filings (10-K/10-Q/8-K). Common values: `Reporting Owner`, `Issuer`, `Filer`. |
| data[].title | string | no | Free-text title from the EDGAR submissions feed (e.g. `8-K - APPLE INC (0000320193) (Filer)`). Useful for full-text search; for structured fields prefer `form_type` + `entity_name`. |
| data[].summary_html | string | yes | Optional HTML summary block from EDGAR (typically empty on Form 4 and 8-K; populated on 13F-HR with structured holdings summary). Treat as untrusted HTML — sanitize before rendering in a browser. |
| data[].filing_size | string | yes | Filing size as a human-readable string (e.g. `"245 KB"`, `"2.1 MB"`). NOT a numeric byte count — for byte-level work parse the string client-side or fetch the document directly. |
| data[].filed_date | string | yes | ISO date `YYYY-MM-DD` of the filing's SEC acceptance date in ET (NOT UTC; matches the date EDGAR's index pages show). For intra-day ordering use `updated_at` which carries a full timestamp. |
| data[].filed_at | string | yes | Frontend-friendly alias of `filed_date`. Same value, kept for backwards compatibility. |
| data[].updated_at | string | no | ISO-8601 UTC timestamp of the last server-side update to this row (e.g. on a backfill refresh). Use as the cursor for incremental sync — sort `updated_at:desc` and persist the max value as your watermark. |
| data[].primary_link | string | yes | Canonical SEC EDGAR URL for the filing's index page (lists all documents in the filing package). Use this as the human-readable link in dashboards. |
| data[].primary_html_url | string | yes | Direct URL of the filing's primary HTML document (the actual 10-K/8-K/13F body, not the index page). For programmatic access use this with `GET /api/v1/sec/document?url=...` or with `GET /api/v1/sec/filings/{accession_number}/html`. |
| data[].document_files | array | yes | JSON array of structured document descriptors `[{sequence, description, documentUrl, type, size}, ...]` (the widely-used commercial SEC-data API's documentFormatFiles shape) extracted from the filing's index page — `documentUrl` is the fully-qualified EDGAR URL. Includes the primary document and each exhibit (EX-99.1 press release, EX-10.1 agreement, GRAPHIC, …). Populated as filings are enriched (or backfilled); null until then. Filter on these via the `exhibits` param / `data[].exhibit_types`. |
| data[].data_files | array | yes | JSON array of XBRL/data file descriptors `[{sequence, description, documentUrl, type, size}, ...]`. Populated on 10-K/10-Q/8-K filings with embedded XBRL; null on filings without XBRL (e.g. older Form 4s). |
| data[].exhibit_types | array | yes | Flat, deduped array of the EDGAR document `type` tokens present on the filing, INCLUDING the EX-NN family for each EX-NN.N exhibit (e.g. an EX-99.1 yields both `"EX-99.1"` and `"EX-99"`). This is the field the `exhibits` filter queries (GIN-indexed). Null until the filing is enriched / backfilled. |
| data[].items | array | yes | Array of 8-K item codes disclosed in this filing (e.g. `["2.02", "9.01"]` for an earnings-release 8-K). Null on non-8-K forms. Use for material-event surveillance — filter on specific item codes (1.01 = Material Definitive Agreement, 2.02 = Earnings, 5.02 = Officer Change, 8.01 = Other). |
| data[].period_of_report | string | yes | ISO `YYYY-MM-DD` period the filing covers (the fiscal-period-end date for 10-K/10-Q, the trade date for Form 4, the report date for 13F-HR). Null for filings without a meaningful period (e.g. some 8-Ks). Differs from `filed_date` — `period_of_report` is the as-of date, `filed_date` is the disclosure date. |
| data[].sic | string | yes | Standard Industrial Classification code (4-digit string, e.g. `3674` = Semiconductors). Null when not assigned. For richer industry categorization, use the resolved ticker's industry classification. |
| data[].all_links | array | yes | Array of every document URL listed on the filing's index page — exhibits, XBRL data, images, the primary document. Pass any element to `GET /api/v1/sec/document?url=...` to fetch its content. |
| data[].first_seen_at | string | no | ISO-8601 UTC timestamp when FinRadar first ingested this filing (typically within seconds of SEC acceptance for filings caught by the RSS poller; longer for backfilled rows). Use for ingest-latency analytics. |
| data[].last_seen_at | string | no | ISO-8601 UTC timestamp of the last time the RSS poller observed this filing on EDGAR. Updated on every poll cycle for filings still in the active feed; frozen for older filings. |
| meta.pagination | object | no | Offset-based pagination metadata: `{total, limit, offset, has_more}`. Use `has_more` as the canonical end-of-iteration signal rather than comparing `data.length` to `limit`. |
| meta.pagination.total | integer | yes | Exact total count of filings matching the query (full-table count, not just the current page), via a `COUNT(*)`. `null` when `include_total=false` was passed (the count over a broad filtered set is a heap scan of every match and dominates latency — use `has_more` for pagination then). Also an approximate whole-table estimate for an unfiltered query. cik/ticker-scoped queries always return the exact count. |
| meta.pagination.has_more | boolean | no | `true` when more pages exist beyond this one. The canonical end-of-iteration signal — always exact (computed from a limit+1 fetch, independent of `total`), so it is reliable even when `total` is `null` (`include_total=false`). When `false`, stop paginating. |
| meta.backfilled_from_edgar | boolean | yes | Present and `true` ONLY when this call triggered an auto-backfill from SEC EDGAR (i.e. the ticker had no local data or only recent RSS-captured data). Absent on the typical hot-path call. Use to surface a UX hint ("first call took a moment to fetch full history"). |
| meta.requested_ticker | string | yes | Echo of the resolved ticker after Phase-53 normalization (e.g. `BRK.A` becomes `BRK-A`). Present only when the request included a `ticker` param. |
| meta.primary_ticker | string | yes | Canonical primary share class for the filer (e.g. for Berkshire Hathaway, returns `BRK-A` even if the user queried `BRK.B`). Use to pivot to the multi-class top-of-book. |
| meta.cik | string | yes | 10-char zero-padded CIK of the resolved ticker. Use as the join key against XBRL, 13F, or insider-filing tables. |
| meta.company | string | yes | Resolved entity name for the ticker (e.g. `Apple Inc.`). Useful as a display label when the user queried by ticker rather than entity_name. |
| meta.requested_ciks | array | yes | (comma-list only) The resolved bare CIKs the query ran over. |
| meta.matched_ciks | array | yes | (comma-list only) The subset of requested CIKs that had >=1 ingested filing. |
| meta.not_ingested | array | yes | (comma-list only) Selectors with no ingested filings: unresolvable tickers + resolved-but-uningested CIKs. Backfilled out-of-band; never inline. |
| meta.list_query | boolean | yes | (comma-list only) `true` when the request used the multi-entity comma-list path. Absent on the single-entity path. |
Sample response
- "status": "success"
- "request_id": "0f14ed05-3a2e-4b76-9c11-1a7c8b3f6de2"
- "timestamp": "2026-05-02T16:30:14.122Z"
- "data":
- "meta":
- "pagination":
- "requested_ticker": "AAPL"
- "primary_ticker": "AAPL"
- "cik": "0000320193"
- "company": "Apple Inc."
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected server-side failure. Retry with backoff; report if persistent. |
Code samples
curl "https://api.finradar.ai/api/v1/sec/filings?api_Token=YOUR_API_KEY&ticker=AAPL%2CMSFT%2CTSLA&cik=320193%2C789019%2C1318605&form_type=4&items=2.02&from_date=2026-01-01&to_date=2026-04-01&sort=filed_at&limit=20&offset=0&include_total=false&exhibits=EX-99" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).