SEC EDGAR submissions JSON recent filings endpoint

data.sec.gov/submissions JSON: Recent Filings Guide

You have a CIK and need the latest 10-K, 10-Q, 8-K, or Form 4. The file you want starts at data.sec.gov/submissions JSON, not the XBRL Company Facts endpoint. Submissions gives you the filing list, dates, accession numbers, form types, and primary documents. Company Facts gives you tagged financial statement facts.

This guide is about the Submissions endpoint only: how the endpoint is shaped, how filings.recent works, how to turn accessionNumber plus primaryDocument into a filing URL, and where developers usually make mistakes. Use it when you need an SEC submissions API workflow for EDGAR recent filings, not a normalized financial statement endpoint. For the XBRL side of SEC JSON, use the SEC data JSON guide. For a wider comparison of raw filings, XBRL, and normalized APIs, see how to get SEC filing data.

Endpoint Overview: data.sec.gov/submissions JSON

Submissions endpoint
An SEC JSON endpoint for one filer's company metadata and filing history.
CIK
Central Index Key, the SEC's unique numeric identifier for a filer. The endpoint requires 10 digits with leading zeros.
Accession number
The EDGAR identifier assigned to a submitted filing. It appears with dashes in the API and without dashes in archive folder paths.
Primary document
The main document filename for the filing package, usually the HTML filing document for 10-K and 10-Q reports.

The Submissions endpoint returns filing history and company metadata for one SEC filer. The URL format is:

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

The ########## segment is the CIK zero-padded to 10 digits. Apple is CIK 320193, so the endpoint is:

https://data.sec.gov/submissions/CIK0000320193.json

The SEC EDGAR API documentation says data.sec.gov hosts RESTful JSON APIs for EDGAR submissions and XBRL data, and that these public data APIs do not require API keys. The same SEC documentation says submissions structures update throughout the day as filings are disseminated, with bulk archives republished nightly. A filing monitor can poll the JSON endpoint, but a large historical backfill should use the bulk ZIP files instead of hammering per-company URLs.

Always send a descriptive User-Agent header. The SEC's EDGAR access guidance asks automated clients to identify the organization and contact.

import requests

headers = {"User-Agent": "YourApp your@email.com"}
cik = "0000320193"

response = requests.get(
    f"https://data.sec.gov/submissions/CIK{cik}.json",
    headers=headers,
    timeout=20,
)
response.raise_for_status()
submissions = response.json()

Recent Filings Fields You Actually Need

The top-level object includes company metadata such as cik, name, sic, sicDescription, tickers, exchanges, and fiscal year information. The filing list lives under filings.recent.

That object is columnar. Instead of an array of filing objects, each field is an array, and every array index describes the same filing. Index i across accessionNumber, form, filingDate, and primaryDocument is one filing record.

Columnar filings.recent fields sharing the same array index
The Submissions endpoint stores recent filings as parallel arrays. Keep the shared index when you build rows.

For Apple, a recent 10-K row looked like this when pulled from the Submissions JSON:

FieldExample valueUse
accessionNumber0000320193-25-000079Filing identifier
form10-KFiling type
filingDate2025-10-31SEC filing date
reportDate2025-09-27Period covered by the report
primaryDocumentaapl-20250927.htmMain document filename
primaryDocDescription10-KHuman-readable document label
isInlineXBRL1Whether the primary filing embeds inline XBRL
size9392337Filing package size in bytes

Other high-value fields in the SEC submissions API include acceptanceDateTime, fileNumber, filmNumber, items, isXBRL, and isXBRLNumeric. Those are useful when you are filtering EDGAR recent filings by event type, structured-data availability, or compliance metadata.

The shape is compact, but it means you should zip arrays together yourself before filtering. Do not sort one field independently. Do not filter form and then reuse the original index on another array unless you keep the same index.

How to Pair accessionNumber and primaryDocument

A filing URL needs three pieces: the numeric CIK without leading zeros, the accession number with dashes removed for the archive folder, and the primaryDocument filename.

CIK padded:        0000320193
CIK archive path:  320193
accessionNumber:  0000320193-25-000079
accession folder: 000032019325000079
primaryDocument:  aapl-20250927.htm

That becomes:

https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/aapl-20250927.htm

The SEC archive path uses the unpadded CIK directory, while the Submissions API URL requires the padded CIK in CIK##########.json. Mixing those two formats is one of the fastest ways to get 404s.

def filing_url(cik_padded: str, accession_number: str, primary_document: str) -> str:
    cik_int = str(int(cik_padded))
    accession_folder = accession_number.replace("-", "")
    return (
        "https://www.sec.gov/Archives/edgar/data/"
        f"{cik_int}/{accession_folder}/{primary_document}"
    )

Filing URL Construction in Practice

The next snippet finds the latest 10-K and builds the SEC archive URL. For event-driven use cases, change the predicate. To monitor recent 8-K filings, filter form == "8-K". To monitor insider activity, filter Forms 3, 4, and 5.

import requests

headers = {"User-Agent": "YourApp your@email.com"}
cik_padded = "0000320193"

response = requests.get(
    f"https://data.sec.gov/submissions/CIK{cik_padded}.json",
    headers=headers,
    timeout=20,
)
response.raise_for_status()
submissions = response.json()

recent = submissions["filings"]["recent"]

ten_k_index = next(
    i for i, form in enumerate(recent["form"])
    if form == "10-K"
)

accession = recent["accessionNumber"][ten_k_index]
primary_doc = recent["primaryDocument"][ten_k_index]

url = filing_url(cik_padded, accession, primary_doc)
print(url)

The Submissions endpoint also has a pagination escape hatch. SEC documentation explains that filings.recent contains at least one year of filings or 1,000 recent filings, whichever is more. If the entity has additional filings, the response references additional JSON files with date ranges. A production backfill should detect those files instead of assuming filings.recent is the entire history.

Submissions vs Company Facts

Submissions answers "what did this company file?" Company Facts answers "what facts did this company report?" They are adjacent, not interchangeable.

TaskUse SubmissionsUse Company Facts
Find latest 10-K URLYesNo
Find recent 8-K filingsYesNo
Get primaryDocument filenameYesNo
Pull reported revenue factsNoYes
Build standardized financial statementsNoYes, with normalization
Detect whether a filing is inline XBRLYesNot the starting point

If you are building a filing feed, start with Submissions. If you are building a financial statement API, Company Facts is the workhorse. The Company Facts JSON is covered in the SEC data JSON format guide, including units, tags, and fact objects.

Fundamentals Hub uses SEC data as the source, then normalizes the financial statement side into consistent API fields for revenue, net income, balance sheet, and cash flow.

Period-explicit AAPL FY2025 API v2 response sample
Submissions finds filing metadata. Normalized fundamentals are a separate layer built from SEC financial statement data.

Parsing Mistakes That Cause Bad Filing Links

The most common bug is treating filings.recent as row-oriented. It is not. Every field is an array, and the row exists only by shared index. Build records like this:

recent = submissions["filings"]["recent"]
records = []

for i, accession in enumerate(recent["accessionNumber"]):
    records.append({
        "accessionNumber": accession,
        "form": recent["form"][i],
        "filingDate": recent["filingDate"][i],
        "reportDate": recent["reportDate"][i],
        "primaryDocument": recent["primaryDocument"][i],
        "isInlineXBRL": recent["isInlineXBRL"][i],
    })

Other mistakes: passing an unpadded CIK to the Submissions API, passing a padded CIK to the archive folder, leaving dashes in the accession folder segment, using primaryDocDescription as a filename, assuming every form has a useful reportDate, and assuming filings.recent contains the complete history for very active filers.

Minimal Recent Filings Parser

This parser keeps the original SEC fields, filters form types, and adds the filing URL.

from typing import Iterable

def recent_filings(submissions: dict, forms: Iterable[str] = ("10-K", "10-Q")):
    cik_padded = str(submissions["cik"]).zfill(10)
    recent = submissions["filings"]["recent"]
    wanted = set(forms)

    for i, form in enumerate(recent["form"]):
        if form not in wanted:
            continue

        accession = recent["accessionNumber"][i]
        primary_doc = recent["primaryDocument"][i]

        yield {
            "cik": cik_padded,
            "company": submissions["name"],
            "form": form,
            "filing_date": recent["filingDate"][i],
            "report_date": recent["reportDate"][i],
            "accession_number": accession,
            "primary_document": primary_doc,
            "filing_url": filing_url(cik_padded, accession, primary_doc),
        }

From there, you can store the records in a database, send alerts, or pass 10-K and 10-Q URLs to a downstream filing parser. If the downstream goal is standardized financial data rather than raw document retrieval, it is cleaner to skip HTML parsing and consume normalized fundamentals directly through an API.

FAQ

Does data.sec.gov/submissions JSON require an API key?

No. SEC documentation says the public data.sec.gov APIs do not require authentication or API keys. Automated clients still need to follow SEC access guidance, including a descriptive User-Agent.

Why does the Submissions endpoint need a padded CIK?

The endpoint path uses a fixed 10-digit CIK format: CIK##########.json. Apple is CIK0000320193. The archive path is different and uses the numeric CIK directory without leading zeros.

Is primaryDocument always the filing I should open?

For most recent public filings, primaryDocument is the main document to open. If you need exhibits, complete submission text, or older filing package details, use the filing index JSON or archive directory as a second step.

Can I get revenue from the Submissions JSON?

No. Submissions gives filing history and metadata. Revenue, assets, net income, and cash flow facts live in XBRL endpoints such as Company Facts. You still need tag mapping and period selection to turn those facts into standardized statements.

How far back does filings.recent go?

SEC documentation says filings.recent contains at least one year of filings or 1,000 recent filings, whichever is more. Additional history can be referenced through separate JSON files listed in the response.

Skip the XBRL Parsing

Fundamentals Hub normalizes SEC EDGAR data into clean JSON. Search 8,000+ public companies and pull standardized statements for covered filings via REST API.

Free to use. 100 requests per 30 days.