Ask an LLM for Toyota's revenue and you get something like "approximately 37 trillion yen." Ask Axiora and you get 37,154,290,000,000 — along with the XBRL element (jppfs_cor:Revenue), the EDINET document ID (S100TQGZ), and a direct link to the filing on EDINET's viewer.
The difference matters. "Approximately 37 trillion" could be last year's number, a subsidiary's number, or a hallucination derived from a blog post that rounded the figure. 37,154,290,000,000 from S100TQGZ is the number Toyota reported in their FY2024 annual securities report, parsed from structured XBRL, traceable to a specific filing.
This is what we mean by "every number has an address."
What an address looks like
Every financial data point returned by Axiora's API carries a source object:
{
"fiscal_year": 2024,
"revenue": 37154290000000,
"source": {
"doc_id": "S100TQGZ",
"edinet_url": "https://disclosure2.edinet-fsa.go.jp/WZEK0040.aspx?S100TQGZ",
"filed_at": "2025-06-25T15:30:00+09:00"
}
}For tools that return field-level detail, we go deeper:
{
"field_sources": {
"revenue": {
"xbrl_element": "jppfs_cor:Revenue",
"context_ref": "CurrentYearDuration_ConsolidatedMember",
"accounting_standard": "JP-GAAP",
"period_start": "2024-04-01",
"period_end": "2025-03-31"
}
}
}This isn't metadata bolted on after the fact. The provenance chain is built into the data retrieval path — the same database join that returns the number also returns its source.
Why this matters for AI agents
When an AI agent calls Axiora's MCP tools, provenance is always included. The agent doesn't need to ask for sources — they arrive with every response. This means:
-
The agent can cite its sources. "Toyota's FY2024 revenue was 37.15 trillion yen (S100TQGZ, filed June 25, 2025)" is verifiable. "About 37 trillion yen" is not.
-
The agent can detect staleness. A
filed_attimestamp lets the agent know whether it's looking at this year's report or last year's. Combined with our freshness validation, stale data gets flagged before it reaches the user. -
The agent can explain nulls. When a field is
null, the agent knows why. IFRS filers don't reportoperating_income(it's not a required line item). JP-GAAP filers don't reportordinary_incomeunder IFRS. These aren't missing data — they're structural differences between accounting standards. -
The agent can qualify comparisons. Comparing Toyota (JP-GAAP) with Sony (IFRS) on revenue? The comparability warning fires automatically: JP-GAAP
売上高and IFRS収益have different scopes. The agent sees this in the response and can explain the caveat.
Provenance as a forcing function
We didn't build provenance because someone asked for it. We built it because it forces every other part of the system to be correct.
When you commit to attaching a source citation to every number, you can't cut corners:
-
The parser must be deterministic. The same filing must always produce the same values. Our parser resolves consolidated vs. standalone contexts, handles iXBRL and traditional XBRL, deduplicates across taxonomy priorities, and produces bit-identical output on re-parse. We test this with 665+ test cases.
-
Nulls must be explained, not hidden. You can't attach a source to a number that doesn't exist — but you can explain why it doesn't exist. Our ontology knows which fields are structurally absent under which accounting standards. A null with a reason is better than a guess.
-
Cross-source discrepancies must surface. When a company reports revenue of 37.154 trillion in their EDINET annual report but 37.5 trillion in their TDNet earnings flash, both are "correct" — they're different filings with different scopes. Our validation layer cross-checks EDINET against TDNet and flags discrepancies above 0.1%.
-
Derived metrics must show their work. Health scores, growth rates, and capital allocation classifications aren't XBRL values — they're computed from XBRL values. Each derived metric now exposes its formula, input values, and the filing those inputs came from.
The architecture
Provenance in Axiora is a response layer, not per-endpoint logic. A single module (provenance.py) handles citation construction:
- Filing-level source:
{doc_id, edinet_url, filed_at}— compact, always available. - Field-level source:
{xbrl_element, context_ref, accounting_standard, period_start, period_end}— available when XBRL element data is populated. - Derived metric source:
{formula, inputs, source_filing}— for computed values like health scores.
The REST API includes provenance when you request it (?include=sources). The MCP interface includes it always — AI agents benefit from provenance on every call, so there's no opt-in.
Both interfaces call the same provenance module. One code path, two transports.
What this enables
With provenance on every data point, we can build features that would be impossible otherwise:
-
Audit trails: A fund manager can trace any number in a report back to the exact EDINET filing. Click the
edinet_urland you're looking at the source document. -
Reproducibility: Query the same company tomorrow and you get the same numbers with the same sources — unless a new filing was published. The
computation_versionin our response metadata tells you exactly which formula version produced each result. -
Comparability warnings: When our ontology detects that two companies use different accounting standards — or different revenue concepts within the same standard — warnings appear automatically in the response. No guessing, no silent errors.
The financial data industry has operated on "trust us, the number is right" for decades. We think the bar should be higher. Every number should have an address. Every null should have a reason. Every comparison should come with caveats.
That's what we built.
Axiora provides structured financial data for 4,000+ Japanese listed companies via REST API and MCP. Read the docs or explore the architecture.