sec-edgar-downloader: fetching SEC filings by ticker or CIK from Python
📈 Download filings from the SEC EDGAR database using Python
At a glance
- What is it?
- sec-edgar-downloader is a small Python package that pulls filings from the SEC EDGAR database, searching by stock ticker or Central Index Key, with rate limiting built in and a user-agent that satisfies the SEC fair access policy. It covers every form type the SEC defines and nothing about the documents themselves.
- Who is it for?
- sec-edgar-downloader suits a Python analyst who needs filings on disk for a handful of tickers, and the combination of ticker and CIK lookup, date filtering, amend handling and rate limiting covers the ordinary cases in a few lines.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 123 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A downloader for the filings, not a parser for them
sec-edgar-downloader is a Python package for downloading company filings from the SEC EDGAR database, and its scope is deliberately narrow. It handles the retrieval problem: finding a company's filings by identifier, filtering them by type and date, and writing them to disk. It does not parse the documents, extract tables or normalise the financial data, and nothing in the documentation suggests it does. The audience is therefore a Python user who needs filing artefacts for later work, whether that is a text search, a hand-check, or a pipeline of their own that consumes the raw files. Searches can be conducted either by stock ticker or by Central Index Key, and the README points at the SEC CIK lookup tool for anyone who cannot find an appropriate ticker. The package is published on PyPI, the documentation is built with Sphinx and hosted on readthedocs, and the repository carries a Makefile, tox.ini, a pre-commit configuration and a requirements directory.
The user-agent is the first thing you have to get right
The basic usage example starts with a comment that looks incidental and is not. You initialise a downloader instance, and you must declare a company name and email address to form a user-agent string that complies with the SEC Edgar's programmatic downloading fair access policy, with a link to the SEC's own guidance on code support. The user-agent takes the form User-Agent: <Company Name> <Email Address>. The package then downloads to the current working directory by default, or to a path you supply. The dependency list explains the rest of the design: requests for the HTTP side and pyrate-limiter at version 4.0.0 or later for the rate limiting that keeps a bulk download from looking like an attack on the SEC's servers. Two details in the code are worth copying exactly. The first is that the company name and email are not decorative, they are the terms of the access policy. The second is that the destination directory is a constructor argument, not a per-call argument, so one downloader instance owns one output location.
One get call covers most filing types and filters
The get method takes a filing type and an identifier, and the identifier can be a ticker or a CIK. The README's examples walk through the range in a compact block:
# Get all 8-K filings for Apple (ticker: AAPL)
dl.get("8-K", "AAPL")
# Get all 8-K filings for Apple, including filing amends (8-K/A)
dl.get("8-K", "AAPL", include_amends=True)
# Get all 8-K filings for Apple after January 1, 2017 and before March 25, 2017
# Note: after and before strings must be in the form "YYYY-MM-DD"
dl.get("8-K", "AAPL", after="2017-01-01", before="2017-03-25")
# Get the five most recent 8-K filings for Apple
dl.get("8-K", "AAPL", limit=5)The keyword arguments are the whole API surface worth memorising. include_amends pulls in the amended versions of a filing, which matters because an amended filing is a separate document with different content. The after and before arguments filter by date and the README insists on the YYYY-MM-DD form. limit caps the count and, given the wording of the example, takes the most recent ones. Other examples cover 10-K filings for Microsoft, 10-Q filings for Visa, the 13F-NT and 13F-HR filings for the Vanguard Group identified by CIK 0000102909, SC 13G filings for Apple and SD filings for Apple. A form type with a space in it, such as SC 13G, is passed as a string, which is a small thing that trips people up.
Looping over supported filings without writing a form list
The advanced usage section shows two patterns that matter for anything larger than a one-off. The first is that the downloader exposes the list of filing types it supports as an attribute, so you can iterate over it without maintaining your own list of form names:
# Get the latest supported filings, if available, for Apple
for filing_type in dl.supported_filings:
dl.get(filing_type, "AAPL", limit=1)The second pattern combines that list with a list of identifiers, mixing tickers and CIKs in the same loop, which is the shape you want when you are collecting the most recent filing of every type for a set of issuers:
equity_ids = ["AAPL", "MSFT", "0000102909", "V", "FB"]
for equity_id in equity_ids:
for filing_type in dl.supported_filings:
dl.get(filing_type, equity_id, limit=1)The advanced section also shows the constructor taking a third argument, the path to save to, and the download_details=False flag on get, which fetches the filing without the accompanying detail documents. Combined with the rate limiter, this is where the fair access policy becomes an operational constraint: a loop over every supported form for every identifier is a lot of requests, and the limiter is what keeps it within the rules. The README does not document what happens when the limit is exceeded, so treat the limiter as a ceiling on request rate and not as a queue with a documented failure mode.
Every form type the SEC defines, listed exhaustively
The package supports downloading all SEC filing types, with 6-K, 8-K, 10-K, DEF 14A and S-1 given as examples, and the README then prints an exhaustive list of the form names you can pass. It runs from 1, 1-A, 1-A POS and the registration forms through the periodic reports, the 13F family of institutional holdings filings, the 40-series tender offer documents, the F-series registration statements, the MA and ABS forms, the proxy statement family DEF 14A and its many variants, the N-1 through N-54 forms, and the NT notification forms, ending with NTN. The list is long because the SEC form catalogue is long, and the value of having it in the documentation is that it doubles as a reference for what exists rather than just what the package handles. The supported_filings attribute is the programmatic version of the same information, and the README links to a description of the different filing types for the semantics.
Where this is the wrong tool
Three limits are visible. The first is that the package downloads documents, so anything requiring structured data from a filing means a second stage that the project does not provide. The second is that the SEC fair access policy is a constraint rather than a courtesy, and the package's own design, with a limiter, a declared user-agent and a note about the policy, makes it clear that high-volume scraping is out of scope. A bulk backfill of every form for every issuer is not something this tool is shaped for. The third is versioning. The release history is 5.1.0 on 2026-02-02, 5.0.3 on 2025-02-14 and 5.0.2 on 2023-10-08, so the package sits at a 5.x line with a minor bump that can change behaviour, and the last push to the repository was on 2026-06-22. The pyproject file declares support for Python 3.10 through 3.14, so an older interpreter is excluded, and the build backend is flit_core with the version held dynamically rather than declared inline.
Licence, packaging and how the project is maintained
The package is MIT licensed, declared through a license file reference in the pyproject file and a license classifier for the MIT License, and the classifiers also mark the development status as Production/Stable. That status is worth reading against the release dates rather than as an assurance on its own, since the tags show roughly a year between 5.0.3 and 5.1.0. The build is deliberately light: requests and pyrate-limiter are the only runtime dependencies, with test extras covering pytest and coverage, and doc extras covering Sphinx and doc8. The Makefile shows the maintenance workflow in full, with a target per supported Python version that creates a virtual environment, installs the requirements files and installs the pre-commit hooks, plus separate targets for tests, linting, documentation and a flit-based distribution build. A release is cut by reading the version out of sec_edgar_downloader/_version.py with a regular expression and pushing a git tag, which is the kind of manual step that tells you to check the changelog rather than assume the tag is current.
Editorial conclusion
sec-edgar-downloader suits a Python analyst who needs filings on disk for a handful of tickers, and the combination of ticker and CIK lookup, date filtering, amend handling and rate limiting covers the ordinary cases in a few lines. It is the wrong tool if you need the filing contents parsed into structured data, because the package downloads documents rather than interpreting them, and it is the wrong tool for high-volume retrieval, because the fair access policy that the user-agent complies with is a rate limit, not a suggestion. Verify first that your requests identify a real company name and email address in the User-Agent, since the package builds it that way for the SEC programmatic access policy, and check the 5.1.0 release against the API you depend on, given that the version line moved from 5.0.x to 5.1.0 in February 2026 and the last push was on 2026-06-22.
Frequently asked questions
How do I install sec-edgar-downloader?
Install and update it with pip install -U sec-edgar-downloader. The package is on PyPI and requires Python 3.10 or later, with 3.10 through 3.14 listed in the classifiers.
Why does the Downloader constructor require a company name and email?
They are used to form a user-agent string of the form User-Agent: <Company Name> <Email Address> that complies with the SEC Edgar's programmatic downloading fair access policy. The README points to the SEC's guidance on code support for more detail.
Can I search for filings by CIK instead of ticker?
Yes. Searches can be conducted either by stock ticker or by Central Index Key, and the README gives 13F-NT and 13F-HR filings for the Vanguard Group as examples using the CIK 0000102909. The SEC CIK lookup tool is linked for finding a CIK when no ticker is available.
How do I limit which filings I download?
The get method accepts include_amends to include amended filings, after and before with dates in the form YYYY-MM-DD, and limit to cap the number of filings, with the example using limit=5 for the five most recent 8-K filings for Apple.
Does sec-edgar-downloader rate limit my requests?
The package depends on pyrate-limiter at version 4.0.0 or later, which is what keeps programmatic access within the SEC fair access policy that the declared user-agent is meant to respect.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jadchaar-sec-edgar-downloader)Was this useful?