Class: SecApi::Xbrl

Inherits:
Object
  • Object
show all
Defined in:
lib/sec_api/xbrl.rb

Overview

Note:

The gem returns element names exactly as provided by sec-api.io without normalizing between US GAAP and IFRS taxonomies. Use SecApi::XbrlData#element_names to discover available elements in any filing.

XBRL extraction proxy for converting SEC EDGAR XBRL filings to structured JSON.

Extraction Workflow:

  1. Client calls to_json() with URL, accession_no, or Filing object

  2. Input is validated locally (URL format, accession format)

  3. Request sent to sec-api.io XBRL-to-JSON endpoint

  4. Response validated heuristically (has statements? valid structure?)

  5. Data wrapped in immutable XbrlData Dry::Struct object

Validation Philosophy (Architecture ADR-5): We use HEURISTIC validation (check structure, required sections) rather than full XBRL schema validation. Rationale:

  • sec-api.io handles taxonomy parsing - we trust their output structure

  • Full schema validation would require bundling 100MB+ taxonomy files

  • We validate what matters: required sections present, data types coercible

  • Catch malformed responses early with actionable error messages

Provides access to the sec-api.io XBRL-to-JSON API, which extracts financial statement data from XBRL filings and returns structured, typed data objects. Supports both US GAAP and IFRS taxonomies.

Examples:

Extract XBRL data from a filing URL

client = SecApi::Client.new(api_key: "your_api_key")
xbrl = client.xbrl.to_json("https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/aapl-20230930.htm")

# Access income statement data
revenue = xbrl.statements_of_income["RevenueFromContractWithCustomerExcludingAssessedTax"]
revenue.first.to_numeric  # => 394328000000.0

Extract using accession number

xbrl = client.xbrl.to_json(accession_no: "0000320193-23-000106")

Extract from Filing object

filing = client.query.ticker("AAPL").form_type("10-K").search.first
xbrl = client.xbrl.to_json(filing)

Discover available XBRL elements

xbrl.element_names  # => ["Assets", "CashAndCashEquivalents", "Revenue", ...]
xbrl.taxonomy_hint  # => :us_gaap or :ifrs

See Also:

Constant Summary collapse

SEC_URL_PATTERN =

Pattern for validating SEC EDGAR URLs.

Returns:

  • (Regexp)

    regex pattern matching sec.gov domains

%r{\Ahttps?://(?:www\.)?sec\.gov/}i
ACCESSION_DASHED_PATTERN =

Pattern for dashed accession number format (10-2-6 digits).

Examples:

"0000320193-23-000106".match?(ACCESSION_DASHED_PATTERN) # => true

Returns:

  • (Regexp)

    regex pattern for format like “0000320193-23-000106”

/\A\d{10}-\d{2}-\d{6}\z/
ACCESSION_UNDASHED_PATTERN =

Pattern for undashed accession number format (18 consecutive digits).

Examples:

"0000320193230001060".match?(ACCESSION_UNDASHED_PATTERN) # => true

Returns:

  • (Regexp)

    regex pattern for format like “0000320193230001060”

/\A\d{18}\z/

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ SecApi::Xbrl

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a new XBRL extraction proxy instance.

XBRL instances are obtained via Client#xbrl and cached for reuse. Direct instantiation is not recommended.

Parameters:



74
75
76
# File 'lib/sec_api/xbrl.rb', line 74

def initialize(client)
  @_client = client
end

Instance Method Details

#to_json(url) ⇒ SecApi::XbrlData #to_json(accession_no:) ⇒ SecApi::XbrlData #to_json(filing, options = {}) ⇒ SecApi::XbrlData

Extracts XBRL financial data from an SEC filing and returns structured, immutable XbrlData object.

Examples:

Extract XBRL data using URL string

client = SecApi::Client.new(api_key: "your_api_key")
xbrl_data = client.xbrl.to_json("https://www.sec.gov/Archives/edgar/data/320193/000032019323000106/aapl-20230930.htm")

Extract XBRL data using accession number

xbrl_data = client.xbrl.to_json(accession_no: "0000320193-23-000106")

Extract XBRL data from Filing object (backward compatible)

filing = client.query.ticker("AAPL").form_type("10-K").search.first
xbrl_data = client.xbrl.to_json(filing)

Overloads:

  • #to_json(url) ⇒ SecApi::XbrlData

    Extract XBRL data from a SEC filing URL.

    Parameters:

    • url (String)

      SEC EDGAR URL pointing to XBRL document

    Returns:

  • #to_json(accession_no:) ⇒ SecApi::XbrlData

    Extract XBRL data using an accession number.

    Parameters:

    • accession_no (String)

      SEC accession number (e.g., “0000320193-23-000106”)

    Returns:

  • #to_json(filing, options = {}) ⇒ SecApi::XbrlData

    Extract XBRL data from a Filing object (backward compatible).

    Parameters:

    • filing (Object)

      Filing object with xbrl_url and accession_number attributes

    • options (Hash) (defaults to: {})

      Optional parameters to pass to the XBRL extraction API

    Returns:

Raises:



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/sec_api/xbrl.rb', line 114

def to_json(input = nil, options = {}, **kwargs)
  request_params = build_request_params(input, kwargs)
  request_params.merge!(options) unless options.empty?

  response = @_client.connection.get("/xbrl-to-json", request_params)

  # Return XbrlData object instead of raw hash.
  # XbrlData.from_api performs heuristic validation:
  # - Checks at least one statement section exists
  # - Dry::Struct validates type coercion (string/numeric values)
  # - Fact objects validate period and value structure
  # Error handling delegated to middleware (Story 1.2)
  begin
    XbrlData.from_api(response.body)
  rescue Dry::Struct::Error, NoMethodError, TypeError => e
    # Heuristic validation failed - data structure doesn't match expected format.
    # This catches issues like missing required fields, wrong types, or malformed
    # fact arrays. Provide actionable context for debugging.
    accession = request_params[:"accession-no"] || "unknown"
    raise ValidationError,
      "XBRL data validation failed for filing #{accession}: #{e.message}. " \
      "This may indicate incomplete or malformed filing data from sec-api.io. " \
      "Check the filing URL and verify the XBRL document is available."
  end
end