Filing API Reference — Access SEC Filing Content, XBRL Data, and Documents
The Filing class represents a single SEC filing and provides comprehensive access to its content, structured data, attachments, and metadata.
Quick example:
from edgar import get_by_accession_number
filing = get_by_accession_number("0000320193-23-000106")
print(f"{filing.company} {filing.form} filed {filing.filing_date}")
# Access content
text = filing.text()
xbrl = filing.xbrl()
# Get form-specific object
tenk = filing.obj() # Returns TenK for 10-K filings
Getting a Filing
from edgar import Company, get_filings, get_by_accession_number
# From a company
company = Company("AAPL")
filing = company.get_filings(form="10-K").latest()
# From a search
filings = get_filings(2024, 1, form="10-K")
filing = filings[0]
# By accession number
filing = get_by_accession_number("0000320193-23-000106")
Core Properties
Basic Information
| Property | Type | Description |
|---|---|---|
cik |
int | Central Index Key of the filing entity |
company |
str | Company name |
form |
str | SEC form type (e.g., "10-K", "10-Q", "8-K") |
filing_date |
str | Date filed with SEC (YYYY-MM-DD) |
accession_no |
str | Unique SEC accession number |
accession_number |
str | Alias for accession_no |
period_of_report |
str | Reporting period end date |
Example:
print(filing.cik) # 320193
print(filing.company) # "Apple Inc."
print(filing.form) # "10-K"
print(filing.filing_date) # "2023-11-03"
print(filing.period_of_report) # "2023-09-30"
Document Properties
| Property | Type | Description |
|---|---|---|
document |
Attachment | Primary display document |
primary_documents |
List[Attachment] | All primary documents |
attachments |
Attachments | All documents and attachments |
exhibits |
Attachments | Exhibits only (subset of attachments) |
Example:
# Access primary document
doc = filing.document
print(doc.document_type)
# Loop through all attachments
for att in filing.attachments:
print(f"{att.sequence}: {att.description}")
# Access exhibits
for exhibit in filing.exhibits:
print(f"Exhibit {exhibit.exhibit_number}: {exhibit.description}")
URL Properties
| Property | Description |
|---|---|
homepage_url |
Filing homepage on SEC website |
filing_url |
URL to primary filing document |
text_url |
URL to text version |
base_dir |
Base directory for all filing files |
Example:
print(filing.homepage_url)
# https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/0000320193-23-000106-index.html
print(filing.filing_url)
# https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/aapl-20230930.htm
Metadata Properties
| Property | Type | Description |
|---|---|---|
header |
FilingHeader | Parsed SGML header information |
is_multi_entity |
bool | Whether filing involves multiple entities |
all_ciks |
List[int] | All CIK numbers in filing |
all_entities |
List[str] | All entity names in filing |
Content Access Methods
Raw Content
html()
def html(self) -> Optional[str]
Returns: HTML string or None if not available
Example:
html = filing.html()
if html:
print(f"HTML length: {len(html)} characters")
text()
def text(self) -> str
Returns: Plain text content
Example:
text = filing.text()
# Search within text
if "artificial intelligence" in text.lower():
print("AI mentioned in filing")
Images contribute nothing by default, which keeps the text that feeds sections,
search and embeddings clean. Pass include_images=True to mark where they were:
text = filing.text(include_images=True)
# ... [Image: nvidialogoa10.jpg] ...
That matters for filings where a chart carries the content — a 10-K's Item 5 stock performance graph is usually an image with no table beside it, so without a placeholder there is nothing to show the reader anything was there.
markdown()
def markdown(
include_page_breaks: bool = False,
start_page_number: int = 0
) -> str
Parameters:
- include_page_breaks (bool): Include page break markers
- start_page_number (int): Starting page number for page breaks
Returns: Markdown formatted content
Example:
md = filing.markdown()
with open("filing.md", "w") as f:
f.write(md)
xml()
def xml(self) -> Optional[str]
Returns: XML string or None
Example:
xml = filing.xml()
if xml:
import xml.etree.ElementTree as ET
root = ET.fromstring(xml)
full_text_submission()
def full_text_submission(self) -> str
Returns: Full submission text including SGML headers
Structured Data Access
xbrl()
def xbrl(self) -> Optional[XBRL]
Returns: XBRL object or None
Example:
xbrl = filing.xbrl()
if xbrl:
# Access financial statements
income = xbrl.statements.income_statement()
balance = xbrl.statements.balance_sheet()
cashflow = xbrl.statements.cash_flow_statement()
See also: XBRL API Reference, Extract Financial Statements Guide
obj() / data_object()
def obj(self)
def data_object(self) # Alias
Returns: Form-specific object (TenK, TenQ, EightK, Form4, etc.)
Form type mappings:
| Form Type | Return Class | Module |
|---|---|---|
| 10-K | TenK | edgar.company_reports |
| 10-Q | TenQ | edgar.company_reports |
| 8-K | EightK | edgar.company_reports |
| 20-F | TwentyF | edgar.company_reports |
| 4 | Form4 | edgar.ownership |
| 3 | Form3 | edgar.ownership |
| 5 | Form5 | edgar.ownership |
| DEF 14A | ProxyStatement | edgar.proxy |
| 13F-HR | ThirteenF | edgar.thirteenf |
| SC 13D | Schedule13D | edgar.beneficial_ownership |
| SC 13G | Schedule13G | edgar.beneficial_ownership |
| NPORT-P | FundReport | edgar.funds.reports |
| 144 | Form144 | edgar.ownership.form144 |
The ownership, proxy and fund classes can also be imported from the top level,
e.g. from edgar import Form4, Schedule13D, ThirteenF, and it is the same class
either way. The company report classes come from edgar.company_reports. The ownership forms span three packages because three
different sections of the Exchange Act require them: Section 16 insiders
(Forms 3/4/5, plus Form 144) in edgar.ownership, Section 13(d)/(g) 5%-and-over
holders (Schedule 13D/G) in edgar.beneficial_ownership, and Section 13(f)
institutional managers (13F-HR) in edgar.thirteenf.
Example:
# For a 10-K filing
tenk = filing.obj()
print(type(tenk)) # <class 'edgar.company_reports.TenK'>
# Access financial statements from TenK object
if tenk.financials:
income = tenk.financials.income_statement
balance = tenk.financials.balance_sheet
cashflow = tenk.financials.cash_flow_statement
# Or use direct properties
income = tenk.income_statement
balance = tenk.balance_sheet
# XBRL report pages (also available via filing.reports)
reports = tenk.reports
Important: The base Filing class does not have a financials property. To access financial data:
- Use filing.obj().financials for 10-K/10-Q filings
- Or use filing.xbrl().statements for any XBRL filing
Incorrect:
# This will fail - Filing has no financials property
financials = filing.financials # AttributeError
Correct:
# Get form-specific object first
tenk = filing.obj()
if tenk.financials:
financials = tenk.financials
# Or use XBRL directly
xbrl = filing.xbrl()
if xbrl:
statements = xbrl.statements
Parsing and Search
parse()
def parse(self) -> Document
Returns: Parsed Document object
Example:
doc = filing.parse()
# Use document methods for structured search
search()
def search(self, query: str, regex: bool = False) -> List[str]
Parameters:
- query (str): Search term or pattern
- regex (bool): Treat query as regex pattern
Returns: List of matching text excerpts
Example:
# Simple text search
results = filing.search("revenue recognition")
print(f"Found {len(results)} mentions")
# Regex search for emails
emails = filing.search(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', regex=True)
sections()
def sections(self) -> List[str]
Returns: List of section names/identifiers
Example:
sections = filing.sections()
for section in sections:
print(section) # "Item 1", "Item 2", etc.
sgml()
def sgml(self) -> FilingSGML
Returns: FilingSGML object with document structure
Example:
sgml = filing.sgml()
for doc in sgml.documents:
print(f"{doc.type}: {doc.sequence}")
Interactive Methods
Viewing and Display
view()
def view(self)
Example:
filing.view() # Shows formatted filing content
open()
def open(self)
Example:
filing.open() # Opens filing in browser
open_homepage()
def open_homepage(self)
Example:
filing.open_homepage() # Opens SEC filing index page
serve()
def serve(self, port: int = 8000)
Parameters:
- port (int): Server port (default: 8000)
Example:
filing.serve(port=8080) # Access at http://localhost:8080
Entity and Related Data
get_entity()
def get_entity(self) -> Union[Company, Entity]
Returns: Company or Entity instance
Example:
entity = filing.get_entity()
print(f"Entity: {entity.name}")
print(f"Industry: {entity.industry}")
as_company_filing()
def as_company_filing(self) -> EntityFiling
Returns: EntityFiling object
related_filings()
def related_filings(self) -> Filings
Returns: Filings collection
Persistence and Serialization
Save and Load
save()
def save(self, directory_or_file: PathLike)
Parameters:
- directory_or_file: Directory or file path
Example:
# Save to directory
filing.save("./data/filings/")
# Save to specific file
filing.save("./data/apple_10k_2023.pkl")
load()
@classmethod
def load(cls, path: PathLike) -> Filing
Parameters:
- path: Path to pickle file
Returns: Filing object
Example:
filing = Filing.load("./data/apple_10k_2023.pkl")
Data Export
to_dict()
def to_dict(self) -> Dict[str, Union[str, int]]
Returns: Dictionary with filing data
Example:
data = filing.to_dict()
print(data.keys())
# dict_keys(['cik', 'company', 'form', 'filing_date', 'accession_no', ...])
from_dict()
@classmethod
def from_dict(cls, data: Dict) -> Filing
Parameters:
- data: Dictionary with filing information
Returns: Filing object
summary()
def summary(self) -> pd.DataFrame
Returns: DataFrame with filing metadata
to_context()
def to_context(self, detail: str) -> str
Parameters:
- detail (str): Level of detail
Returns: Context string
Download
download()
def download(
self,
data_directory: Optional[str] = None,
compress: bool = True,
compression_level: int = 6,
upload_to_cloud: bool = False,
disable_progress: bool = False
)
Parameters:
- data_directory: Download directory (defaults to Edgar data directory)
- compress: Compress downloaded files (default: True)
- compression_level: gzip level 1-9 (default: 6)
- upload_to_cloud: Upload to cloud storage after download
- disable_progress: Disable progress display
Example:
# Download with defaults
filing.download()
# Custom directory without compression
filing.download(data_directory="./raw_filings", compress=False)
Common Recipes
Extract revenue from 10-K
from edgar import Company
company = Company("AAPL")
filings = get_filings(2024, 1, form="10-K")
filing = filings.latest()
# Get TenK object
tenk = filing.obj()
# Access financials
if tenk.financials:
income = tenk.financials.income_statement
print(income)
Search across multiple filings
from edgar import get_filings
filings = get_filings(2024, 1, form="8-K").head(100)
for filing in filings:
results = filing.search("cybersecurity")
if results:
print(f"{filing.company} ({filing.filing_date}): {len(results)} mentions")
Download exhibits from a filing
filing = get_by_accession_number("0001234567-24-000001")
for exhibit in filing.exhibits:
print(f"Downloading {exhibit.exhibit_number}: {exhibit.description}")
exhibit.download(f"./exhibits/{exhibit.document}")
Convert filing to markdown for analysis
filing = company.get_filings(form="10-K").latest()
# Export to markdown — tables, links and images all preserved
md = filing.markdown()
# Save for LLM processing
with open("filing_for_analysis.md", "w") as f:
f.write(md)
include_page_breaks is deprecated
It routes the document through the legacy renderer, which drops images. Removed in 6.0.
Error Handling
try:
filing = get_by_accession_number("0000320193-23-000106")
# Check content availability
html = filing.html()
if html is None:
print("HTML not available")
# Check XBRL availability
xbrl = filing.xbrl()
if xbrl is None:
print("No XBRL data")
# Get structured object
obj = filing.obj()
except Exception as e:
print(f"Error: {e}")
Performance Tips
- Check before accessing - Test for None before processing optional data
- Use obj() for structured data - More efficient than parsing HTML
- Cache expensive operations - Store results of xbrl(), text(), etc.
- Filter attachments - Use
exhibitsproperty instead of filtering all attachments
Efficient pattern:
# Get structured object once
obj = filing.obj()
# Check before using
if obj and obj.financials:
income = obj.financials.income_statement
# Process income statement
See Also
- Filings API Reference - Working with filing collections
- Company API Reference - Company-specific filing access
- XBRL API Reference - XBRL data extraction
- Working with Filings Guide - Practical filing operations
- Extract Financial Statements - Getting financial data
- Filing Attachments Guide - Working with documents and exhibits