Back to Blog

data.sec.gov/submissions API: JSON Structure, recent Filings Arrays & Pagination

The submissions API returns a company's entire filing history as one JSON document. This is the exact structure of that JSON, field by field, verified against the live endpoint, including the parallel-array gotcha and how to page into older filings.

The Endpoint

https://data.sec.gov/submissions/CIK##########.json

The CIK must be zero-padded to exactly 10 digits. Apple's CIK is 320193, so the filename is CIK0000320193.json. Request CIK320193.json and you get a 404. (Note the asymmetry: Archives URLs strip the leading zeros instead.)

No API key. No authentication. Two hard requirements: a User-Agent header in the form YourName [email protected] (missing it returns 403), and roughly 10 requests per second maximum before the SEC temporarily blocks your IP.

Top-Level Metadata Fields

The response starts with entity metadata (fields verified live against CIK0000320193.json):

Field Type Example (Apple)
cik string "0000320193"
name string "Apple Inc."
tickers array ["AAPL"]
exchanges array ["Nasdaq"]
sic / sicDescription string "3571" / "Electronic Computers"
entityType string "operating"
stateOfIncorporation string "CA"
fiscalYearEnd string (MMDD) "0926"

Other top-level fields include ein, lei, description, website, investorWebsite, category, addresses (with mailing and business objects), phone, flags, formerNames, ownerOrg, insiderTransactionForOwnerExists, insiderTransactionForIssuerExists, and finally filings.

filings.recent: The Parallel-Array Gotcha

filings.recent is not an array of filing objects. It is an object of parallel arrays, and index i across every array describes one filing. The exact keys, verified live:

{
  "filings": {
    "recent": {
      "accessionNumber":    ["0000320193-25-000079", ...],
      "filingDate":         ["2025-10-31", ...],
      "reportDate":         ["2025-09-27", ...],
      "acceptanceDateTime": ["2025-10-31T06:01:36.000Z", ...],
      "act":                ["34", ...],
      "form":               ["10-K", ...],
      "fileNumber":         ["001-36743", ...],
      "filmNumber":         ["...", ...],
      "items":              ["", ...],
      "core_type":          ["10-K", ...],
      "size":               [9392337, ...],
      "isXBRL":             [1, ...],
      "isInlineXBRL":       [1, ...],
      "isXBRLNumeric":      [1, ...],
      "primaryDocument":    ["aapl-20250927.htm", ...],
      "primaryDocDescription": ["10-K", ...]
    },
    "files": [ ... ]
  }
}

So recent['form'][51] == "10-K" means the filing at index 51 has accession number recent['accessionNumber'][51], filing date recent['filingDate'][51], and primary document recent['primaryDocument'][51]. To turn a row into a document URL, follow our Archives URL construction guide: strip dashes from the accession number, drop the CIK's leading zeros, append primaryDocument.

recent holds at least one year of filings, up to roughly the 1,000 most recent (Apple's block has exactly 1,000 entries).

filings.files: Paging Into Older Filings

Filings older than the recent window are split into continuation files, listed under filings.files:

"files": [
  {
    "name": "CIK0000320193-submissions-001.json",
    "filingCount": 1236,
    "filingFrom": "1994-01-26",
    "filingTo": "2015-05-27"
  }
]

Fetch each continuation file from https://data.sec.gov/submissions/{name}. Each one contains the same parallel arrays as filings.recent (at the top level of the file, without the filings.recent wrapper). Large filers may have several continuation files; use filingFrom/filingTo to pick the date range you need.

Worked Example: Filter for 8-K Filings in Python

import requests

HEADERS = {'User-Agent': 'YourName [email protected]'}

def get_filings(cik, form_type='8-K'):
    padded = str(int(cik)).zfill(10)   # CIK must be 10 digits in the URL
    url = f'https://data.sec.gov/submissions/CIK{padded}.json'
    data = requests.get(url, headers=HEADERS).json()

    recent = data['filings']['recent']
    results = []
    for i, form in enumerate(recent['form']):
        if form == form_type:
            results.append({
                'accessionNumber': recent['accessionNumber'][i],
                'filingDate':      recent['filingDate'][i],
                'reportDate':      recent['reportDate'][i],
                'primaryDocument': recent['primaryDocument'][i],
                'items':           recent['items'][i],   # 8-K item numbers
            })
    return results

for f in get_filings('320193')[:5]:
    acc = f['accessionNumber'].replace('-', '')
    print(f"{f['filingDate']}  8-K  items={f['items']}")
    print(f"  https://www.sec.gov/Archives/edgar/data/320193/{acc}/{f['primaryDocument']}")

For 8-Ks, the items array is especially useful: it lists the triggering item numbers (e.g. "2.02" for earnings results), so you can filter for earnings 8-Ks without downloading any documents.

Rate Limits and Best Practices

FAQ

What is the URL format for the SEC submissions API?

https://data.sec.gov/submissions/CIK##########.json with the CIK zero-padded to exactly 10 digits, e.g. CIK0000320193.json for Apple.

How are filings stored in filings.recent?

As parallel arrays: accessionNumber, filingDate, form, primaryDocument, and the rest are separate arrays, and index i across all of them describes one filing.

How do I get filings older than the recent block?

Read filings.files for continuation objects (name, filingCount, filingFrom, filingTo) and fetch each from https://data.sec.gov/submissions/{name}. They contain the same parallel arrays.

Does the submissions API require an API key?

No. It is free and unauthenticated, but you must send a User-Agent header with contact info and stay under about 10 requests per second.

Related Guides