Skip to content

XBRL API Reference

The XBRL module provides comprehensive parsing and processing of XBRL (eXtensible Business Reporting Language) data from SEC filings. It includes support for statement standardization, multi-period analysis, and advanced querying capabilities.

Module Overview

The XBRL module is organized into several key components:

  • Core Classes: XBRL, XBRLS for parsing and managing XBRL documents
  • Statement Processing: Statements, Statement for working with financial statements
  • Facts Querying: FactsView, FactQuery for querying XBRL facts
  • Multi-Period Analysis: StitchedStatements, StitchedStatement for comparative analysis
  • Standardization: StandardConcept for normalizing company-specific concepts
  • Rendering: RenderedStatement for formatted output

Core Classes

XBRL

The main class for parsing and working with XBRL documents from SEC filings.

from edgar.xbrl import XBRL

class XBRL:
    """Main XBRL parser integrating all components of the XBRL parsing system."""

Factory Methods

from_filing()

@classmethod
def from_filing(cls, filing: Filing) -> XBRL

Create an XBRL instance from a Filing object.

Parameters: - filing: SEC filing object containing XBRL data

Returns: XBRL instance

Example:

from edgar import Company
from edgar.xbrl import XBRL

company = Company("AAPL")
filing = company.latest("10-K")
xbrl = XBRL.from_filing(filing)

from_directory()

@classmethod
def from_directory(cls, directory: str) -> XBRL

Create an XBRL instance from a directory containing XBRL files.

Parameters: - directory: Path to directory containing XBRL files

Returns: XBRL instance

from_files()

@classmethod
def from_files(cls, files: List[str]) -> XBRL

Create an XBRL instance from a list of XBRL files.

Parameters: - files: List of file paths to XBRL documents

Returns: XBRL instance

Core Properties

statements

@property
def statements(self) -> Statements

Access to all financial statements in the XBRL document.

Returns: Statements object for accessing individual statements

Example:

# Access different statement types
balance_sheet = xbrl.statements.balance_sheet()
income_statement = xbrl.statements.income_statement()
cash_flow = xbrl.statements.cash_flow_statement()

facts

@property
def facts(self) -> FactsView

Access to all XBRL facts with querying capabilities.

Returns: FactsView object for querying facts

Example:

# Query facts by concept
revenue_facts = xbrl.facts.by_concept("Revenue")

# Convert to DataFrame for analysis
facts_df = xbrl.facts.to_dataframe()

Statement Methods

get_statement()

def get_statement(self, statement_type: str) -> Optional[Statement]

Get a specific financial statement by type.

Parameters: - statement_type: Statement type ("BalanceSheet", "IncomeStatement", "CashFlowStatement", etc.)

Returns: Statement object or None if not found

render_statement()

def render_statement(self, statement_type: str, **kwargs) -> RenderedStatement

Render a financial statement with rich formatting.

Parameters: - statement_type: Statement type to render - **kwargs: Additional rendering options

Returns: RenderedStatement object

Example:

# Render balance sheet
rendered = xbrl.render_statement("BalanceSheet")
print(rendered)

# Render with custom options
rendered = xbrl.render_statement("IncomeStatement", 
                                show_percentages=True,
                                max_rows=50)

Data Conversion

to_pandas()

def to_pandas(self) -> pd.DataFrame

Convert XBRL facts to a pandas DataFrame.

Returns: DataFrame with all facts and their attributes

Example:

# Convert to DataFrame for analysis
df = xbrl.to_pandas()
print(df.columns)  # ['concept', 'value', 'period', 'label', ...]

# Filter for specific concepts
revenue_df = df[df['concept'].str.contains('Revenue', case=False)]

XBRLS

Container class for managing multiple XBRL documents for multi-period analysis.

from edgar.xbrl import XBRLS

class XBRLS:
    """Container for multiple XBRL objects enabling multi-period analysis."""

Factory Methods

from_filings()

@classmethod
def from_filings(cls, filings: List[Filing]) -> XBRLS

Create an XBRLS instance from multiple filings.

Parameters: - filings: List of Filing objects

Returns: XBRLS instance

Example:

from edgar import Company
from edgar.xbrl import XBRLS

company = Company("AAPL")
filings = company.get_filings(form="10-K").head(3)  # Get 3 years
xbrls = XBRLS.from_filings(filings)

Properties

statements

@property
def statements(self) -> StitchedStatements

Access to stitched statements showing multi-period data.

Returns: StitchedStatements object

Example:

# Get multi-period statements
income_stmt = xbrls.statements.income_statement()
balance_sheet = xbrls.statements.balance_sheet()

# Render multi-period view
print(income_stmt.render())

Statement Classes

Statements

High-level interface for accessing financial statements from a single XBRL document.

class Statements:
    """High-level interface to all statements in an XBRL document."""

Statement Access Methods

balance_sheet()

def balance_sheet(self) -> Optional[Statement]

Get the balance sheet statement.

Returns: Statement object or None

income_statement()

def income_statement(self) -> Optional[Statement]

Get the income statement.

Returns: Statement object or None

cash_flow_statement()

def cash_flow_statement(self) -> Optional[Statement]

Get the cash flow statement.

Returns: Statement object or None

statement_of_equity()

def statement_of_equity(self) -> Optional[Statement]

Get the statement of equity.

Returns: Statement object or None

comprehensive_income()

def comprehensive_income(self) -> Optional[Statement]

Get the comprehensive income statement.

Returns: Statement object or None

Example:

statements = xbrl.statements

# Access different statement types
if statements.balance_sheet():
    bs = statements.balance_sheet()
    print(f"Total Assets: {bs.get_concept_value('Assets')}")

if statements.income_statement():
    is_stmt = statements.income_statement()
    print(f"Revenue: {is_stmt.get_concept_value('Revenue')}")

Statement

Individual financial statement with analysis and rendering capabilities.

class Statement:
    """A single financial statement extracted from XBRL data."""

Core Methods

render()

def render(self, **kwargs) -> RenderedStatement

Render the statement with rich formatting.

Parameters: - **kwargs: Rendering options (show_percentages, max_rows, etc.)

Returns: RenderedStatement object

to_dataframe()

def to_dataframe(self) -> pd.DataFrame

Convert statement to pandas DataFrame.

Returns: DataFrame with statement data

get_concept_value()

def get_concept_value(self, concept: str) -> Optional[Any]

Get the value for a specific concept.

Parameters: - concept: Concept name to look up

Returns: Concept value or None

Example:

statement = xbrl.statements.income_statement()

# Render the statement
rendered = statement.render()
print(rendered)

# Convert to DataFrame
df = statement.to_dataframe()

# Get specific values
revenue = statement.get_concept_value("Revenue")
net_income = statement.get_concept_value("NetIncomeLoss")

Facts Querying

FactsView

Provides a view over all XBRL facts with analysis and querying methods.

class FactsView:
    """View over all facts with analysis methods."""

Query Methods

by_concept()

def by_concept(self, pattern: str, exact: bool = False) -> FactQuery

Filter facts by concept name.

Parameters: - pattern: Pattern to match against concept names - exact: If True, require exact match; otherwise, use regex

Returns: FactQuery object for further filtering

by_label()

def by_label(self, pattern: str, exact: bool = False) -> FactQuery

Filter facts by element label.

Parameters: - pattern: Pattern to match against labels - exact: If True, require exact match; otherwise, use regex

Returns: FactQuery object for further filtering

by_value()

def by_value(self, min_value: float = None, max_value: float = None) -> FactQuery

Filter facts by value range.

Parameters: - min_value: Minimum value threshold - max_value: Maximum value threshold

Returns: FactQuery object for further filtering

by_period()

def by_period(self, start_date: str = None, end_date: str = None) -> FactQuery

Filter facts by period range.

Parameters: - start_date: Start date (YYYY-MM-DD format) - end_date: End date (YYYY-MM-DD format)

Returns: FactQuery object for further filtering

Analysis Methods

pivot_by_period()

def pivot_by_period(self, concepts: List[str] = None) -> pd.DataFrame

Create a pivot table showing concepts by period.

Parameters: - concepts: List of concepts to include (default: all)

Returns: DataFrame with concepts as rows and periods as columns

time_series()

def time_series(self, concept: str) -> pd.Series

Get time series data for a specific concept.

Parameters: - concept: Concept name

Returns: pandas Series with time series data

Data Conversion

to_dataframe()

def to_dataframe(self) -> pd.DataFrame

Convert facts to pandas DataFrame.

Returns: DataFrame with all facts and metadata

Example:

facts = xbrl.facts

# Query by concept
revenue_query = facts.by_concept("Revenue")
revenue_facts = revenue_query.execute()

# Query by label and value
large_expenses = facts.by_label("expense").by_value(min_value=1000000)
expense_facts = large_expenses.to_dataframe()

# Time series analysis
revenue_ts = facts.time_series("Revenue")
print(revenue_ts.head())

# Pivot analysis
pivot_df = facts.pivot_by_period(["Revenue", "NetIncomeLoss"])

FactQuery

Fluent query builder for filtering and manipulating XBRL facts.

class FactQuery:
    """A query builder for XBRL facts with fluent interface."""

Filtering Methods

All filtering methods return self for method chaining.

by_concept()

def by_concept(self, pattern: str, exact: bool = False) -> FactQuery

by_label()

def by_label(self, pattern: str, exact: bool = False) -> FactQuery

by_value()

def by_value(self, min_value: float = None, max_value: float = None) -> FactQuery

by_period()

def by_period(self, start_date: str = None, end_date: str = None) -> FactQuery

by_statement()

def by_statement(self, statement_type: str) -> FactQuery

Filter facts by statement type.

Parameters: - statement_type: Statement type to filter by

Returns: FactQuery object for method chaining

Execution Methods

execute()

def execute(self) -> List[Dict]

Execute the query and return matching facts.

Returns: List of fact dictionaries

to_dataframe()

def to_dataframe(self) -> pd.DataFrame

Execute the query and return results as DataFrame.

Returns: DataFrame with query results

first()

def first(self) -> Optional[Dict]

Get the first matching fact.

Returns: First fact dictionary or None

count()

def count(self) -> int

Count matching facts without retrieving them.

Returns: Number of matching facts

Example:

# Chain multiple filters
query = (xbrl.facts
         .by_concept("Revenue")
         .by_period(start_date="2023-01-01")
         .by_value(min_value=1000000))

# Execute in different ways
facts_list = query.execute()
facts_df = query.to_dataframe()
first_fact = query.first()
count = query.count()

Multi-Period Analysis

StitchedStatements

Interface for accessing multi-period statements that combine data across multiple XBRL documents.

class StitchedStatements:
    """Interface for multi-period statements."""

Statement Access Methods

Similar to Statements but returns StitchedStatement objects:

balance_sheet()

def balance_sheet(self) -> Optional[StitchedStatement]

income_statement()

def income_statement(self) -> Optional[StitchedStatement]

cash_flow_statement()

def cash_flow_statement(self) -> Optional[StitchedStatement]

Example:

# Multi-period analysis
stitched_statements = xbrls.statements
income_stmt = stitched_statements.income_statement()

# Shows multiple years of data
print(income_stmt.render())

StitchedStatement

Individual statement showing multi-period data with comparative analysis.

class StitchedStatement:
    """Individual stitched statement showing multi-period data."""

Analysis Methods

render()

def render(self, **kwargs) -> RenderedStatement

Render multi-period statement with rich formatting.

to_dataframe()

def to_dataframe(self) -> pd.DataFrame

Convert to DataFrame with periods as columns.

Standardization

StandardConcept

Represents a standardized concept that normalizes company-specific terminology.

class StandardConcept:
    """Standardized concept representation."""

Properties

name

@property
def name(self) -> str

Standardized concept name.

label

@property
def label(self) -> str

Standardized human-readable label.

Example:

# Standardization is applied automatically in statements
statement = xbrl.statements.income_statement()
df = statement.to_dataframe()

# Check for standardized vs original labels
print(df[['label', 'original_label']].head())

Rendering

RenderedStatement

Formatted statement output with rich console display capabilities.

class RenderedStatement:
    """Rich formatted statement output."""

Display Methods

str()

def __str__(self) -> str

Plain text representation of the statement.

rich()

def __rich__(self) -> RichRenderable

Rich console representation with formatting.

Example:

# Rich rendering in console
rendered = xbrl.render_statement("BalanceSheet")
print(rendered)  # Displays with rich formatting

# Plain text for export
text_output = str(rendered)

Utility Functions

stitch_statements()

def stitch_statements(statements: List[Statement]) -> StitchedStatement

Combine multiple statements into a stitched statement.

Parameters: - statements: List of Statement objects to combine

Returns: StitchedStatement object

render_stitched_statement()

def render_stitched_statement(stitched_statement: StitchedStatement, **kwargs) -> RenderedStatement

Render a stitched statement with formatting.

Parameters: - stitched_statement: StitchedStatement to render - **kwargs: Rendering options

Returns: RenderedStatement object

to_pandas()

def to_pandas(obj: Union[XBRL, Statement, FactsView]) -> pd.DataFrame

Convert various XBRL objects to pandas DataFrame.

Parameters: - obj: Object to convert (XBRL, Statement, or FactsView)

Returns: DataFrame representation

Advanced Usage Examples

Multi-Period Financial Analysis

from edgar import Company
from edgar.xbrl import XBRLS

# Get multiple years of data
company = Company("AAPL")
filings = company.get_filings(form="10-K").head(3)
xbrls = XBRLS.from_filings(filings)

# Analyze income statement trends
income_stmt = xbrls.statements.income_statement()
revenue_trend = income_stmt.get_trend("Revenue")
revenue_growth = income_stmt.calculate_growth("Revenue")

print(f"Revenue Growth: {revenue_growth.iloc[-1]:.2%}")

Complex Fact Querying

from edgar import Company
from edgar.xbrl import XBRL

company = Company("MSFT")
filing = company.latest("10-K")
xbrl = XBRL.from_filing(filing)

# Complex query with multiple filters
high_value_revenue = (xbrl.facts
                     .by_concept("Revenue")
                     .by_value(min_value=50000000000)  # $50B+
                     .by_period(start_date="2023-01-01")
                     .to_dataframe())

# Pivot analysis
pivot_df = xbrl.facts.pivot_by_period([
    "Revenue", 
    "NetIncomeLoss", 
    "OperatingIncomeLoss"
])

Statement Comparison

# Compare statements across different companies
companies = ["AAPL", "MSFT", "GOOGL"]
statements = []

for ticker in companies:
    company = Company(ticker)
    filing = company.latest("10-K")
    xbrl = XBRL.from_filing(filing)
    if xbrl.statements.income_statement():
        statements.append(xbrl.statements.income_statement())

# Create comparison DataFrame
comparison_data = []
for stmt in statements:
    df = stmt.to_dataframe()
    comparison_data.append(df)

# Analyze key metrics across companies
key_metrics = ["Revenue", "NetIncomeLoss", "OperatingIncomeLoss"]
for metric in key_metrics:
    print(f"\n{metric} Comparison:")
    for i, stmt in enumerate(statements):
        value = stmt.get_concept_value(metric)
        if value:
            print(f"  {companies[i]}: ${value/1e9:.1f}B")

Import Reference

# Core classes
from edgar.xbrl import XBRL, XBRLS

# Statement classes
from edgar.xbrl import Statements, Statement
from edgar.xbrl import StitchedStatements, StitchedStatement

# Facts querying
from edgar.xbrl import FactsView, FactQuery
from edgar.xbrl import StitchedFactsView, StitchedFactQuery

# Standardization and rendering
from edgar.xbrl import StandardConcept, RenderedStatement

# Utility functions
from edgar.xbrl import stitch_statements, render_stitched_statement, to_pandas

Error Handling

from edgar.xbrl import XBRL, XBRLFilingWithNoXbrlData

try:
    xbrl = XBRL.from_filing(filing)
except XBRLFilingWithNoXbrlData:
    print("Filing does not contain XBRL data")
except Exception as e:
    print(f"Error parsing XBRL: {e}")

# Check for statement availability
if xbrl.statements.income_statement():
    income_stmt = xbrl.statements.income_statement()
    df = income_stmt.to_dataframe()
else:
    print("Income statement not found")

Performance Tips

  1. Use specific queries - Filter facts early to reduce processing time
  2. Cache XBRL objects - Parsing is expensive, reuse when possible
  3. Limit statement rendering - Use max_rows parameter for large statements
  4. Batch processing - Use XBRLS for efficient multi-period analysis

See Also