SEC EDGAR Downloader
sec-edgar-downloader is a Python package designed for efficiently downloading company filings from the SEC EDGAR database. Currently at version 5.1.0, it underwent a full rewrite in 5.0.0 to leverage the SEC's official EDGAR API and integrates formal rate-limiting using `pyrate-limiter` to comply with SEC fair access policies (10 requests per second). The library actively maintains support for recent Python versions and has a consistent release cadence with new features and fixes.
Common errors
-
HTTPError: 403 Client Error: Forbidden for url: https://www.sec.gov/...
cause The SEC server rejected the request, usually due to a missing or invalid `User-Agent` header, or exceeding the rate limit (10 requests/second).fixEnsure the `Downloader` is initialized with valid `company_name` and `email_address` parameters. For example: `dl = Downloader('My Company', 'me@example.com')`. Avoid making excessive requests outside the library's internal rate limiting. -
TypeError: Downloader.__init__() got an unexpected keyword argument 'user_agent'
cause In versions 5.0.0 and later, the `user_agent` parameter in the `Downloader` constructor was replaced by separate `company_name` and `email_address` parameters to explicitly comply with SEC requirements.fixUpdate your `Downloader` initialization from `Downloader(user_agent='...', ...)` to `Downloader(company_name='...', email_address='...', ...)`. -
AttributeError: 'Downloader' object has no attribute 'get_filings_by_period'
cause Version 5.0.0 was a complete rewrite, and many older methods (like `get_filings_by_period` or parameters like `before_date`/`after_date` instead of `before`/`after`) were removed or renamed.fixConsult the latest documentation for `sec-edgar-downloader` (version 5.x.x) and update your code to use the current `get()` method signature and available parameters. -
ImportError: cannot import name 'Downloader' from 'sec_edgar_downloader'
cause This usually indicates an installation issue, or the environment is picking up an older, incompatible version of the library.fixEnsure the package is correctly installed with `pip install -U sec-edgar-downloader` and that your Python environment is clean and correctly configured to use the installed package.
Warnings
- breaking Version 5.1.0 dropped support for Python 3.8 and 3.9. The package now requires Python 3.10 or higher.
- breaking Version 5.0.0 involved a full package rewrite to utilize the SEC's new official EDGAR API. Code written for versions prior to 5.0.0 may no longer be compatible due to significant API changes.
- breaking Version 5.1.0 upgraded `pyrate-limiter` from 3.x to 4.x. If you were using custom rate-limiting decorators or directly interacting with `pyrate-limiter`'s API, the `raise_when_fail` and `max_delay` parameters have been removed from `Limiter` initialization, and the decorator pattern changed from `@limiter(mapping_function)` to `@limiter.as_decorator(name='...', weight=1)`.
- gotcha The SEC requires a specific `User-Agent` header for programmatic access, formatted as 'Company Name AdminContact@YourDomain.com'. Failing to provide a valid `User-Agent` during `Downloader` initialization will result in 403 Forbidden errors.
- gotcha The SEC imposes a fair access policy of 10 requests per second. The library includes internal rate-limiting, but aggressive or improperly configured usage (e.g., in parallel processes without proper synchronization) can still lead to temporary IP blocks (403 Forbidden errors) from the SEC.
Install
-
pip install sec-edgar-downloader
Imports
- Downloader
from sec_edgar_downloader import Downloader
Quickstart
import os
from sec_edgar_downloader import Downloader
# It's crucial to set a User-Agent to comply with SEC's fair access policy.
# Replace with your company name and admin contact email.
# Example: 'MyCompanyName AdminContact@mycompany.com'
company_name = os.environ.get('SEC_EDGAR_COMPANY_NAME', 'My Test Company')
email_address = os.environ.get('SEC_EDGAR_EMAIL', 'test@example.com')
# Initialize a downloader instance. Filings will be saved to the current working directory by default.
# You can specify a different download_folder: dl = Downloader(company_name, email_address, '~/sec_filings')
dl = Downloader(company_name, email_address)
try:
# Download the latest 10-K filing for Apple (AAPL)
# The 'limit' parameter controls the number of most recent filings to download.
count = dl.get('10-K', 'AAPL', limit=1)
print(f"Successfully downloaded {count} filing(s) for AAPL.")
# Download all 8-K filings for Microsoft (MSFT) after a specific date
count = dl.get('8-K', 'MSFT', after='2023-01-01')
print(f"Successfully downloaded {count} 8-K filing(s) for MSFT after 2023-01-01.")
except Exception as e:
print(f"An error occurred: {e}")
print("Ensure your User-Agent is properly set and you are not exceeding SEC rate limits.")