The secedgar Python library pulls any public company's SEC filings—10-K annual reports, 10-Q quarterly statements, 8-K event notices—directly from EDGAR without manual searching. Install it, specify a ticker and filing type, and the files land on your machine in seconds.

Key Takeaways

  • secedgar automates bulk downloads for single or multiple companies using ticker symbols
  • Filter by filing type (10-K, 10-Q, 8-K), date range, and document count
  • Downloads come directly from SEC's public EDGAR database—no API key or authentication required
Difficulty: Intermediate Time needed: 20–30 minutes For: Python users who analyze company financials, automate research workflows, or build datasets from public filings

Before You Start

This guide assumes you understand basic Python syntax and can run scripts from a terminal. You should know how to install packages with pip and navigate file directories. The secedgar library works on Windows, macOS, and Linux. You do not need an SEC account or API credentials—EDGAR is a free public database.

The SEC limits automated access to 10 requests per second. The secedgar library enforces rate limits internally, but if you run multiple scripts simultaneously, the SEC may temporarily block your IP. For production use involving thousands of filings, plan for throttling delays.

What You Need

  • Python 3.7 or newer—check your version by running python --version in your terminal
  • pip package manager—bundled with Python 3.4 and later
  • Internet connection with access to sec.gov (some corporate networks block EDGAR)
  • Valid company ticker symbols—the same tickers you'd find on Yahoo Finance or Google Finance ($AAPL, $MSFT)
  • At least 100 MB free disk space—a single 10-K can exceed 5 MB

Step 1: Install the secedgar Library

Open your terminal and run pip install secedgar. The library downloads automatically with its dependencies, including requests for HTTP handling and lxml for HTML parsing. Installation typically completes in 30–60 seconds. Verify by running python -c "import secedgar; print(secedgar.__version__)"—if you see a version number without errors, you're ready.

Without a successful install, none of the download commands will execute.

a white cube with a yellow and blue logo on it
Photo by Rubaitul Azad / Unsplash

Step 2: Create a Download Directory

Choose where you want filings saved. Create a dedicated folder—sec_filings in your home directory, for example. In Python: import os; os.makedirs("sec_filings", exist_ok=True). The exist_ok=True parameter prevents errors if the folder already exists. This directory will hold subfolders for each company, organized by ticker symbol.

The secedgar library automatically creates company-specific subdirectories, but you need to specify the parent folder. Organizing from the start prevents confusion when you're working with filings from multiple companies.

Step 3: Import the Library and Specify Your Target

Open a Python script or interactive session. Import the filing type you want: from secedgar import FilingType, CompanyFilings. Then define your target company: company = CompanyFilings(cik_lookup="AAPL", filing_type=FilingType.FILING_10K). Replace AAPL with any valid ticker symbol.

The cik_lookup parameter accepts either ticker symbols or CIK numbers (the SEC's unique company identifier). Ticker symbols are simpler. The filing_type parameter controls which forms you download: FILING_10K for annual reports, FILING_10Q for quarterly reports, FILING_8K for material events.

Step 4: Set Download Parameters

Control how many filings to retrieve by adding a count parameter: company = CompanyFilings(cik_lookup="AAPL", filing_type=FilingType.FILING_10K, count=5). This downloads the five most recent 10-K filings. Omit the count parameter to download all available filings for that type—be cautious. Some companies have decades of filings.

You can also filter by date range using start_date and end_date parameters, both accepting datetime objects. For example: from datetime import datetime; start = datetime(2020, 1, 1); end = datetime(2023, 12, 31) limits downloads to filings submitted between those dates. This prevents downloading irrelevant historical data when you only need recent filings.

Step 5: Execute the Download

Run the download command: company.save("sec_filings"). Replace sec_filings with your chosen directory path. The library connects to the SEC EDGAR search interface, retrieves filing URLs, and downloads each document sequentially. Progress appears in your terminal as each file saves. A single 10-K typically downloads in 5–10 seconds depending on connection speed.

Downloaded filings appear as .txt files inside company-specific subdirectories. The filenames include the accession number (the SEC's unique filing identifier) and the filing date. You can open these files in any text editor—they contain the full HTML and XBRL content submitted by the company.

Step 6: Batch Download Multiple Companies

For multiple companies, create a list of tickers: tickers = ["AAPL", "MSFT", "GOOGL"]. Loop through the list: for ticker in tickers: company = CompanyFilings(cik_lookup=ticker, filing_type=FilingType.FILING_10K, count=3); company.save("sec_filings"). This downloads the three most recent 10-K filings for each company in the list.

Batch operations are where secedgar delivers real efficiency. Manually downloading filings for 50 companies might take hours through the SEC website—the library completes it in minutes. The rate-limiting logic prevents SEC blocks, but expect proportional time increases as your company list grows. Downloading one filing for 100 companies takes roughly the same time as downloading 100 filings for one company.

Step 7: Verify Downloaded Files

Navigate to your download directory. You should see subdirectories named after each ticker symbol. Inside each, check for .txt files with names like 0000320193-23-000077.txt. Open one file—the content begins with <SEC-DOCUMENT> and includes the full filing text. If files are missing or empty, check your internet connection and confirm the ticker symbols are valid.

The SEC filing structure includes multiple documents per submission: the main report, exhibits, XBRL data. By default, secedgar downloads the complete filing package. If you only need the main document, you'll need to parse the downloaded file and extract the primary <DOCUMENT> section. For structured financial data, consider extracting XBRL using a separate parsing library like python-xbrl.

Common Problems

HTTPError 403 or "Access Denied": The SEC blocked your IP for exceeding 10 requests per second. Wait 10 minutes before retrying. If the problem persists, check whether a firewall or VPN is interfering—some networks route traffic through shared IPs the SEC has already rate-limited. Use time.sleep(1) between downloads if you're manually looping without the library's built-in delays.

FileNotFoundError or empty directory: The ticker symbol you specified does not exist in the SEC database, or the company has no filings of that type. Verify the ticker on the SEC company search page. Not all publicly traded companies file with the SEC—foreign firms listed on U.S. exchanges may use Form 20-F instead of 10-K.

ModuleNotFoundError: No module named 'secedgar': The library did not install correctly or you're running Python in a different environment than where you installed it. Confirm installation with pip list | grep secedgar. If using virtual environments, activate the correct environment before running your script. If using Anaconda, install via conda install -c conda-forge secedgar instead of pip.

Best Practices

  • Set a user-agent header when making bulk downloads—the SEC requests this for tracking. Add company.user_agent = "Your Name your.email@domain.com" before calling .save(). This prevents your IP from being flagged as a bot.
  • Download during off-peak hours (after 9 PM Eastern) when SEC server load is lower. Filings released during market hours may experience temporary access delays due to high traffic.
  • Store CIK numbers instead of tickers for long-term projects—tickers can change after mergers or rebrands, but CIK numbers remain permanent. Look up CIK numbers once and save them in a reference file.
  • Parse downloaded filings with BeautifulSoup or lxml to extract tables, exhibits, or specific sections. Raw SEC filings are HTML-heavy and difficult to read without parsing. For quantitative analysis, combine secedgar with pandas to build backtesting datasets from historical financial statements.
  • Archive filings by submission date rather than download date—use the accession number's embedded date to organize files chronologically. This makes time-series analysis more reliable.

When Not to Use This

Do not rely on secedgar for real-time filings or time-sensitive event monitoring. There is a delay between SEC submission and EDGAR database indexing—typically 15–30 minutes. For live tracking of 8-K material events, subscribe to the SEC's RSS feeds or use a commercial data provider.

Do not use secedgar if you need structured financial data in machine-readable format. While the library downloads XBRL files, it does not parse them—you'll need additional tools like Arelle or XBRL-US API to extract balance sheet line items. For pre-processed financial statements, consider the Financial Modeling Prep API or Alpha Vantage.

Do not attempt to download all filings for the entire SEC database—EDGAR contains millions of documents going back to the 1990s. Such requests will trigger permanent IP blocks. If you need comprehensive historical data, use the SEC's bulk download service instead, which provides quarterly archives of all filings.

FAQ

How do I scrape SEC filings programmatically without hitting rate limits?

Use the secedgar library's built-in rate limiting—it enforces the SEC's 10 requests per second rule automatically. Add a user-agent header with your contact information so the SEC can notify you if there's an issue. For large-scale scraping, download the SEC's quarterly bulk data files instead of making individual requests.

How do I fetch only 10-K files without downloading other filing types?

Set filing_type=FilingType.FILING_10K when creating the CompanyFilings object. This filters the download to annual reports only. For 10-Q quarterly reports, use FilingType.FILING_10Q. For 8-K event disclosures, use FilingType.FILING_8K. The library supports all major SEC form types.

How do I access the EDGAR database with code if a company changed its ticker symbol?

Use the company's CIK number instead of the ticker symbol. CIK numbers never change, even after mergers or rebrands. Look up the CIK on the SEC company search page, then pass it to cik_lookup as a string: CompanyFilings(cik_lookup="0000320193", ...). This works for any company with an SEC filing history.

Can I download filings for private companies or foreign firms?

Only if they file with the SEC. Private companies that issue public debt or have more than 500 shareholders may file periodic reports. Foreign companies listed on U.S. exchanges file Form 20-F (annual report) or Form 6-K (current report) instead of 10-K and 8-K. Check the SEC database first—if no filings exist, the company is not required to disclose under U.S. securities law.