How it works
How we keep the as-reported hierarchy of financial statements
This description reflects the system as of October 20, 2026. It may change as we improve it.
1. What “as-reported hierarchy” means
A balance sheet or income statement is a nested table such as “Assets → Current assets → Cash and deposits”. Which line rolls up into which total, and in what order lines appear, is written in the XBRL (the electronic format for financial data) that the company files. ZENITH Code keeps that structure and attaches the depth, parent, order and subtotal flag to every line item.
view_columnStandardised columns (for screening and comparison)
Data mapped to columns with the same name for every company, such as revenue, operating income and total assets. Good for cross-company comparison and screening. Items that do not fit a standard column do not appear.
account_treeAs-reported hierarchy (for faithful display)
The filed line items in their original order and nesting. Good for reproducing one company’s statements on screen. Items the company created itself stay as rows whether or not they could be mapped.
Shipping only standardised columns is convenient, but relying only on mapped keys drops company-specific items (extension tags). ZENITH Code provides both as separate outputs.
2. Why we designed it this way
Showing a statement as filed needs a different approach from standardisation. Four reasons shaped the design.
Do not drop company-specific items
Filers can create their own tags (extension tags) for items that are not in the standard taxonomy. Relying on mapped keys loses them, so we keep the original structure and order without depending on mapping.
Tell subtotals from detail lines
We use the XBRL calculation linkbase (which items add up or subtract into which total) to tell subtotals from detail lines, so that totals are not counted twice as if they were details.
Reproduce the original order
The order in the XBRL presentation linkbase (which items appear under which heading, in what order) becomes the display order as is.
From per-company exceptions to a generic process
The first engine accumulated per-company special cases, and an exception added for one company sometimes broke another. In 2026 we rebuilt it as a generic process based on the tree (parent-child) structure.
A regression we learned from
When amendments were applied on top of mapped keys, items went missing and balance sheets stopped balancing. That is why we now treat the original structure, amendments included, as the unit of work.
3. How it is built
Besides the numbers, XBRL carries definitions of how items relate to each other (linkbases). ZENITH Code reads them in this order.
- 1
Presentation linkbase → tree and order
Build the tree from parent-child links and their order, and sort by that order.
- 2
Role → which statement
Classify each role URI of the presentation linkbase as balance sheet, income statement, cash flow statement, comprehensive income, statement of changes in equity, or summary.
- 3
Calculation linkbase → arithmetic relations
Read which item rolls into which total and whether it is added (+1) or subtracted (−1); used for subtotal detection and checks.
- 4
Labels → line-item names
Use the filer’s own extension labels first, then the standard label dictionary.
data_objectWhat each line item carries
In the /stable/financial-statement-full response, each element of a statement’s items array is one line of the statement. Each line carries the following.
| Field | Meaning |
|---|---|
| depth | Depth in the tree. Larger numbers are further inside. Major sections (such as assets) and sub-sections (such as current assets) have fixed depths, and levels for headings that are not shown are closed up. |
| parent_key | The parent row in the tree. null for top-level rows. |
| sort | Order number. Sorting ascending gives the original order (a depth-first walk of the tree). |
| is_abstract | Whether the row is a heading. Headings have child rows and no amount of their own. |
| is_subtotal | Whether the row is a subtotal or total. For IFRS and US GAAP it is decided only from the shape of the calculation linkbase; label text is not read. For Japanese GAAP it uses the standard definitions plus the calculation linkbase. Unknown company-specific tags are treated as detail lines. |
| negated | Whether the filing asks for the row to be shown as negative (the “△” mark in Japanese statements). The sign of the value is not changed; only the display flag is carried. |
| master_key | The mapped standard key, used to connect the row with the standardised columns. null when the row could not be mapped. |
| ancestor_section_key | The larger total section the row belongs to: current assets, non-current liabilities, net assets, etc. for the balance sheet; operating income, ordinary income, income before income taxes and net income for the income statement; operating, investing and financing sections for the cash-flow statement. It is null for rows outside those sections and for the statement of changes in equity and the comprehensive-income statement, which have no sections (tidied up on 20 October 2026). |
| original_tag | The original XBRL tag as filed. Company-specific tags appear as is. |
| label_ja / label_en | Japanese and English item names. The English label may be empty when the filing has none. |
| source | Where the row’s value was taken from (for example xbrl). |
| context_id | The XBRL context that says which point in time or period the value refers to (for example the quarter-end instant or the year-to-date period). null for heading rows. |
| has_anomaly | A check flag per period (one filing), not per row. It sits directly under statements and reflects checks for missing key items and the consistency of the cash balance. |
items sit under statements.statements in the response, grouped by statement section (BS, PL, CF, CI, SS and so on). Rows also carry key and tree_tag as identifiers.
account_treeA real example
The first few rows of the sample response for TOYOTA MOTOR CORPORATION (7203), 2026-06 (Q1, IFRS), rendered as is: sorted by sort and indented by depth.
Top of the balance sheet (BS)
| Line item | Original tag (original_tag) | Amount (JPY million) |
|---|---|---|
資産Heading | jpigp_cor_AssetsIFRSAbstract_bs | |
Current AssetsHeading | jpigp_cor_CurrentAssetsIFRSAbstract_bs | |
Cash and Cash Equivalents | jpigp_cor_CashAndCashEquivalentsIFRS_bs | 10,343,085 |
Notes and Accounts Receivable | jpigp_cor_TradeAndOtherReceivablesCAIFRS_bs | 4,019,645 |
Receivables related to financial servicesExtensionNo master_key | tse-qcediffr-72030_ReceivablesRelatedToFinancialServicesCAIFRS_bs | 14,086,337 |
Top of the income statement (PL)
| Line item | Original tag (original_tag) | Amount (JPY million) |
|---|---|---|
営業収益HeadingExtension | tse-qcediffr-72030_SalesRevenuesIFRSAbstract_pl | |
Sales of productsExtensionNo master_key | tse-qcediffr-72030_SalesOfProductsIFRS_pl | 12,142,263 |
Financing operationsExtensionNo master_key | tse-qcediffr-72030_FinancingOperationsIFRS_pl | 1,383,137 |
Total net revenuesSubtotalExtensionNo master_key | tse-qcediffr-72030_TotalNetRevenuesIFRS_pl | 13,525,400 |
売上原価並びに販売費及び一般管理費HeadingExtension | tse-qcediffr-72030_CostsAndExpensesIFRSAbstract_pl |
The sample is real data fetched from our development environment on 2026-10-23. “Extension” marks an item the company created itself; “No master_key” marks a row not mapped to a standard key. Even a standard tag has an empty master_key when there is nothing to map it to.
4. Company-specific items and name matching
Company-specific items stay as rows even when they cannot be mapped. Mapping is extra information for connecting to the standardised columns, not a condition for keeping a row.
- check_circleRows that could not be mapped have an empty master_key, and their key is built from the English item name plus the name of the section they belong to.
- check_circleMatching is tried in this order: exact match → prefix match → match after stripping prefixes.
- check_circleWhen tags spelled for different accounting standards compete for the same standard key, the spelling that matches the accounting standard declared in the filing wins first; within that, alias priority and whether a value exists decide.
- check_circleTags that lose the competition are still kept as line items.
The mapping dictionary has 308 standard items (items mapped to XBRL tags; another 71 items are calculated or derived) and about 4,700 XBRL tag names (the size of the definition, not the number of matches in real data).
5. Why we can publish fast
We pull earnings-release XBRL at short intervals and build the hierarchy right after each pull.
| Document | Timing (weekdays) |
|---|---|
| Earnings releases (TDnet) — fetch | Every 30 minutes (:01 and :31 past each hour) |
| Earnings releases — parse and build the hierarchy | At :15 past each hour, 9:15–18:15 JST |
| Disclosures outside those hours | The daily run at 8:00 JST the next morning (same process) |
| Annual securities reports etc. (EDINET) | Fetched hourly; parsed per document at :20 past each hour |
A real example: on September 16, 2026, the release was fetched at 09:02 and the hierarchy build finished at 09:16 JST.
Measured: TDnet earnings summaries with XBRL are parsed a median of about 46 minutes after disclosure, and 90% within 50 minutes (measured on 526 summaries over the last 30 days, as of 2026-10-16). Delivery time differs by type of data. As with other data, the API reflects TDnet-based data daily by 16:30 and EDINET-based data daily by 19:00 (Japan time).
This is estimated from the processing schedule and one real day, not a guarantee. Outages and late-published amendments are exceptions. The X-Data-As-Of (point in time of the data) and X-Data-Version (version of the data) response headers tell you how current an API response is.
mergeWhen releases, annual reports and amendments overlap
- check_circleFor the same company, fiscal period and quarter, the most recently filed disclosure wins.
- check_circleFor each statement section (balance sheet, income statement and so on), the latest disclosure that actually has numbers is used.
- check_circleForecasts and dividends always come from earnings releases; segments and similar data are added from annual securities reports.
- check_circleThe one exception: per-share metrics are replaced only from amendment filings.
6. Differences by accounting standard
Japanese GAAP, IFRS and US GAAP are identified from the form code of the document and the accounting standard declared on the cover page. A branch for JMIS (Japan’s Modified International Standards) also exists.
| Item | Japanese GAAP | IFRS | US GAAP |
|---|---|---|---|
| Equity attributable to owners of the parent | Net assets − non-controlling interests − share acquisition rights | Equity attributable to owners of the parent in the statement of changes in equity | Shareholders’ equity |
| Subtotal detection | Standard definitions + calculation linkbase | Calculation linkbase shape only (labels not read) | Calculation linkbase shape only (labels not read) |
| Detailed hierarchy | Built from the presentation linkbase | Built from the presentation linkbase | Summary only for filings without detailed tags |
Equity means “equity attributable to owners of the parent” under every standard. Which method applies is decided by the combination of tags disclosed, not by the name of the standard.
ruleOther rules
- check_circleRevenue follows the item name used on the cover page. When a period has values under two standards, the later standard is used.
- check_circleIn the year of a change of accounting standard, values under a standard other than the declared one are not published.
- check_circleWhen detailed consolidated statements exist but an item only has a non-consolidated value, it is left blank in the consolidated column rather than filled in.
- check_circleIrregular fiscal periods that are not 12 months long are excluded from annualised metrics.
- check_circleWhen a company changes its fiscal year-end, the 12-month full-year row is kept as is and the fourth-quarter report is added as Q4.
- check_circleFilings without detailed tags, such as some quarterly cumulative filings and US GAAP filings, show the summary only.
7. Trial and error
We have spent about two years parsing and analyzing financial statements while running our other services. Getting to the current system took more than 100 rebuilds and re-parses. The most recent full-scale rebuilds covering every company and document on record are the following three, in August–September 2026.
- August 2026Reprocessed all annual securities reports (EDINET) with the new process.
- September 6–7, 2026Rebuilt every company (about 8 hours). Several of the 9 acceptance checks fixed in advance failed.
- September 8–9, 2026Ran it again after fixes and passed the acceptance checks.
buildMain failures and fixes
| What happened | Fix | Result |
|---|---|---|
| Per-company special cases piled up, and an exception for one company broke another | Rebuilt as a generic process based on the tree structure | — |
| Identity-based checks produced large numbers of warnings that could not be fixed (3,856 flagged periods) | Switched to detecting missing key items, keeping only the cash-balance identity | — |
| Different documents were packed in one ZIP and their trees got mixed | Parse each document separately | Wrong splits: 6 → 0 |
| Income statements in the single-statement format (profit and comprehensive income in one table) were dropped along with their tree | Build that format as an income statement | Missing income statements: 3,550 rows → 7 |
| The key used to store trees did not include the document, so an amended tree was overwritten by an older one (6 of 446 periods) | Added the document ID to the storage key | — |
loopHow we verify
- check_circleWe repeat one cycle: inspect → fix → rebuild → re-measure.
- check_circleInspection uses about 50 read-only check queries. They never modify data.
- check_circleIf counts move, we suspect the check before the data. Acceptance criteria are fixed before a run starts.
- check_circleErrors on the filer’s side are recorded one by one rather than patched with correction rules.
8. Scale
Counted on 20 October 2026 by reading the data pipeline's production data for the 4,014 listed equities. A document is counted once per company × fiscal period × quarter. Some US GAAP filings have no detailed tags and are handled as summary only.
| Metric | Count |
|---|---|
| Companies with hierarchy data | 3,785 |
| Documents with hierarchy data (company × period × quarter) | 149,370 |
| Of which full-year documents | 41,548 |
| Average line items per full-year document | 192 |
| Maximum depth (balance sheet; income and cash-flow statements up to 4) | 6 |
| Share of company-specific tags (latest full year, %) | 2 |
| Documents with at least one company-specific tag (latest full year, %) | 84 |
As of 2026-10-20.
9. Using it via the API
Pass a stock code to /stable/financial-statement-full to get every statement of a period with its hierarchy. You can choose the period with fiscalPeriod (YYYY-MM) and quarter (Q1, Q2, Q3, FY); without them you get the latest period.
Example request
curl "https://api.zenithcode.net/stable/financial-statement-full?symbol=7203&fiscalPeriod=2026-06&quarter=Q1" \ -H "x-api-key: YOUR_API_KEY"
format_indent_increaseRebuilding the statement in your UI
- check_circleSort items by sort, ascending.
- check_circleIndent each row by its depth.
- check_circleShow rows with is_subtotal = true in bold, and leave the amount empty for is_abstract rows.
- check_circleFor rows with negated = true you can add a “△” or minus mark to follow display conventions (the value’s sign is unchanged).
JavaScript example: print the balance sheet with indentation
const res = await fetch(
"https://api.zenithcode.net/stable/financial-statement-full?symbol=7203",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const [row] = await res.json();
const items = row.statements.statements.BS.items;
for (const it of [...items].sort((a, b) => a.sort - b.sort)) {
const indent = " ".repeat(it.depth);
const label = it.is_subtotal ? `[${it.label_ja}]` : it.label_ja;
console.log(indent + label, it.is_abstract ? "" : it.value);
}hubRelation to the standardised endpoints
To compare across companies or to get fixed columns, use the standardised endpoints. Rows with a master_key are linked to the same key as the standardised columns.
- Income statement (/stable/income-statement)
- Balance sheet (/stable/balance-sheet-statement)
- Cash flow statement (/stable/cash-flow-statement)
10. FAQ
How is this different from the standardised income statement and similar endpoints?
The standardised endpoints return values mapped to the same column names for every company, which suits comparison and screening. financial-statement-full returns the filed line items with their order, parent-child structure and subtotals, which suits reproducing one company’s statements on screen.
What are rows with an empty master_key?
Rows that could not be mapped to a standard key, most often items the company created itself. The rows are kept, so you can display them with original_tag and the item names (label_ja, label_en).
Is the detailed hierarchy available for every company?
No. Filings without detailed tags, such as some quarterly cumulative filings and some US GAAP filings, show the summary only.
How long after a disclosure does it reach the API?
The API reflects TDnet-based data daily by 16:30 and EDINET-based data daily by 19:00 (Japan time). Measured: TDnet earnings summaries with XBRL are parsed a median of about 46 minutes after disclosure, and 90% within 50 minutes (measured on 526 summaries over the last 30 days, as of 2026-10-16). Outages and late amendments are exceptions.
What happens when an amendment is filed?
For the same company, period and quarter, the most recently filed disclosure wins, and for each statement section the latest disclosure that actually has numbers is used. Per-share metrics are replaced only from amendment filings.
Can I compare companies that use different accounting standards?
Equity is aligned across standards to mean “equity attributable to owners of the parent”, but how line items are structured differs by standard and by company. For cross-company comparison we recommend the standardised endpoints.
This page explains how the data is produced. It does not guarantee the accuracy or completeness of the data, and it is not a recommendation for any investment decision.
Try the hierarchy data
The docs list every field and show a sample response.

