Open source toolkit to facilitate working with the SEC EDGAR database.
This toolkit is not affiliated with, endorsed by, or maintained by the U.S. Securities and Exchange Commission (SEC). It is an independent, open-source project designed to facilitate access to publicly available EDGAR data.
The SEC EDGAR Toolkit provides easy-to-use libraries for both TypeScript/JavaScript and Python developers to access and work with SEC filing data from the EDGAR database. This monorepo contains:
- TypeScript Package: Full-featured TypeScript/JavaScript library with type safety
- Python Package: Pythonic interface for data analysis and research
- Search and retrieve SEC filings (10-K, 10-Q, 8-K, etc.)
- Parse and extract structured data from filings
- Extract individual items from filings (Item 1, Item 1A, etc.)
- XML parsing for SEC ownership forms (Forms 3, 4, and 5)
- High-performance async/await support
- Available for both npm and pip installation
- Type-safe interfaces (TypeScript) and type hints (Python)
- Rate limiting and retry logic built-in
- Comprehensive documentation and examples
| Feature | TypeScript/JavaScript | Python |
|---|---|---|
| Company Search | β By ticker, CIK, name | β By ticker, CIK, name |
| Filing Retrieval | β All filing types | β All filing types |
| Date Filtering | β From/to date ranges | β From/to date ranges |
| XBRL Data Access | β Company facts, concepts, frames | β Company facts, concepts, frames |
| XML Parsing | β Forms 3, 4, 5 | β Forms 3, 4, 5 |
| Item Extraction | β 10-K, 10-Q, 8-K items | β 10-K, 10-Q, 8-K items |
| Rate Limiting | β Automatic (10 req/sec) | β Automatic (10 req/sec) |
| Retry Logic | β Exponential backoff | β Exponential backoff |
| Type Safety | β Full TypeScript types | β Type hints (mypy) |
| Async Support | β Promise-based | β async/await |
| Error Handling | β Typed exceptions | β Typed exceptions |
| User Agent | β Required | β Required |
| As-reported statements (instance document + presentation linkbases) | β | β |
| Dimensional XBRL (segments, products, geography) | β | β |
| Filing-scoped statements (FilingSummary/R-files, incl. segments) | β | β |
| Full-text search (efts.sec.gov, 2001+) | β | β |
| 13F institutional holdings parsing | β | β |
| Typed exhibit metadata (EX-99.1, ...) | β | β |
| Multiple reporting owners + footnotes on Forms 3/4/5 | β | β |
| Foreign private issuers (20-F items, IFRS statements) | β | β |
| Amendment-aware filing lookups | β | β |
| Form objects (OwnershipForm, EightK, TenK, TenQ) | β | β |
| Typed item enums (TenKItem, TenQItem, EightKItem) | β | β |
| Global recent-filings feed | β | β |
| Deep filing-history pagination | β | β |
| Caching | β In-memory LRU + on-disk (opt-in) | β On-disk (opt-in) + 24-hour ticker cache |
pnpm add sec-edgar-toolkit
# or
npm install sec-edgar-toolkit
# or
yarn add sec-edgar-toolkitpip install sec-edgar-toolkit # minimal: requests is the only dependency
pip install 'sec-edgar-toolkit[pandas]' # + DataFrame output (get_fact, statement DataFrames)
pip install 'sec-edgar-toolkit[full]' # + pandas and lxml (faster, more forgiving XML parsing)The base install covers the whole API surface with only requests as a
dependency: filings, form objects, item extraction, facts, and
filing-scoped statements. Only the DataFrame-returning helpers need
pandas. When lxml is present it is used for XML parsing, and the
standard library handles it otherwise.
import { Company, setIdentity, getCurrentFilings, TenKItem, EightKItem } from 'sec-edgar-toolkit';
setIdentity('YourApp/1.0 (your.email@example.com)');
// Companies resolve by ticker or CIK
const company = await Company.lookup('AAPL');
console.log(company.name, company.cik, await company.sicDescription());
// Filings come back newest first, with .latest()
const latest10K = (await company.getFilings({ form: '10-K' })).latest();
// Form-specific objects: TenK/TenQ sections, EightK events, Form 3/4/5 ownership
const tenK = await latest10K.obj();
console.log(tenK.riskFactors.slice(0, 500));
const mda = await latest10K.getItem(TenKItem.MANAGEMENT_DISCUSSION_AND_ANALYSIS);
const eightK = await (await company.getFilings({ form: '8-K' })).latest().obj();
if (eightK.hasItem(EightKItem.RESULTS_OF_OPERATIONS)) {
console.log('Earnings 8-K', eightK.pressReleases);
}
const form4 = await (await company.getFilings({ form: '4' })).latest().obj();
for (const tx of form4.transactions) {
console.log(form4.ownerName, tx.transactionCode, tx.shares, tx.pricePerShare);
}
// XBRL: company facts and filing-scoped statements (including segments)
const facts = await company.getFacts();
const revenue = facts.getFact('RevenueFromContractWithCustomerExcludingAssessedTax');
const xbrl = latest10K.xbrl();
const statements = await xbrl.getAllStatements();
// Financial statements as period tables
const financials = await company.getFinancials();
const income = financials.incomeStatement();
// Global near-real-time filings feed
for (const filing of await getCurrentFilings('8-K', 10)) {
console.log(filing.filingDate, filing.companyName, filing.formType);
}The original chainable query-builder client stays available:
import { createClient } from 'sec-edgar-toolkit';
const client = createClient({
userAgent: "YourApp/1.0 (your.email@example.com)"
});
// Find company and get filings
const company = await client.companies.lookup("AAPL");
const filings = await company.filings.formTypes(["10-K"]).recent(5).fetch();
// Extract items from filing
const filing = filings[0];
const items = await filing.extractItems(); // Get all items
const riskFactors = await filing.getItem("1A"); // Get specific itemfrom sec_edgar_toolkit import Company, set_identity
set_identity("YourApp/1.0 (your.email@example.com)")
# Companies resolve by ticker or CIK
company = Company("AAPL")
print(company.name, company.cik, company.sic_description)
# Filings come back newest first, with .latest()
latest_10k = company.get_filings(form="10-K").latest()
# Form-specific objects: TenK/TenQ sections, EightK events, Form 3/4/5 ownership
tenk = latest_10k.obj()
print(tenk.risk_factors[:500])
# Items are addressable by typed enums (TenKItem, TenQItem, EightKItem)
from sec_edgar_toolkit import EightKItem, TenKItem
mda = latest_10k.get_item(TenKItem.MANAGEMENT_DISCUSSION_AND_ANALYSIS)
eightk = company.get_filings(form="8-K").latest().obj()
if eightk.has_item(EightKItem.RESULTS_OF_OPERATIONS):
print("Earnings 8-K")
form4 = company.get_filings(form="4").latest().obj()
for tx in form4.transactions:
print(form4.owner_name, tx.transaction_code, tx.shares, tx.price_per_share)
# XBRL: company facts and filing-scoped statements (including segments)
facts = company.get_facts()
revenue = facts.get_fact("RevenueFromContractWithCustomerExcludingAssessedTax")
xbrl = latest_10k.xbrl()
statements = xbrl.get_all_statements()
# Financial statements as DataFrames
financials = company.get_financials()
income = financials.income_statement()
# Global near-real-time filings feed
from sec_edgar_toolkit import get_current_filings
for filing in get_current_filings(form="8-K", page_size=10):
print(filing.filing_date, filing.company_name, filing.form_type)A chainable query-builder client is also available:
from sec_edgar_toolkit import create_client
client = create_client("YourApp/1.0 (your.email@example.com)")
company = client.companies.lookup("AAPL")
filings = company.filings.form_types(["10-K"]).recent(5).fetch()Extract individual items from SEC filings:
# Python example
filing = company.get_filing("10-K")
items = filing.extract_items()
# Output structure:
{
"1": "Item 1. Business\nThe Company designs, manufactures...",
"1A": "Item 1A. Risk Factors\nThe Company's business...",
"1B": "Item 1B. Unresolved Staff Comments\nNone.",
"2": "Item 2. Properties\nThe Company's headquarters...",
# ... all other items
}This project includes Docker support for both development and production environments.
sec-edgar-toolkit:typescript- TypeScript/Node.js production imagesec-edgar-toolkit:python- Python production imagesec-edgar-toolkit:dev- Combined development environment
# Build specific targets
docker build --target typescript -t sec-edgar-toolkit:typescript .
docker build --target python -t sec-edgar-toolkit:python .
docker build --target dev -t sec-edgar-toolkit:dev .# TypeScript development with hot reload
docker-compose up typescript-dev
# Python development with test coverage
docker-compose up python-dev
# Combined interactive development environment
docker-compose up dev
# Production builds
docker-compose up typescript-prod python-prod-
TypeScript Development:
docker-compose up typescript-dev # Runs tests in watch mode on http://localhost:3000 -
Python Development:
docker-compose up python-dev # Runs pytest with coverage reports -
Interactive Development:
docker-compose up dev # Combined environment with both TypeScript and Python # Access via: docker-compose exec dev bash
This project was inspired by and builds upon the excellent work of the SEC EDGAR community. Special thanks to the maintainers and contributors of these projects that have paved the way for accessible financial data:
- python-edgar - For pioneering Python-based EDGAR access
- sec-api - For demonstrating clean API design patterns
- edgar-crawler - For innovative approaches to document parsing
- pyedgar - For comprehensive filing download capabilities
- sec-edgar-downloader - For simplified bulk download functionality
- sec-api - For bringing EDGAR data to the Node.js ecosystem
- edgarWebR - For making EDGAR data accessible to data scientists using R
We're grateful for the open-source community's collective effort in democratizing access to public financial data. This toolkit aims to contribute to this ecosystem by providing a modern, type-safe, and multi-language solution.
We welcome contributions! Please see our Contributing Guide for details.
This software is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
This means:
- You can use, modify, and distribute this software
- If you modify and distribute it, you must release your changes under AGPL-3.0
- If you run a modified version on a server, you must provide the source code to users
For commercial licensing options or other licensing inquiries, please contact stefano@amorelli.tech.
See the LICENSE file for the full license text.
Copyright Β© 2025 Stefano Amorelli. All rights reserved.