Evid Invest
Guide for developers and analysts

How to get 30 years of financial statements into ChatGPT or Claude

Three routes that work today — an MCP server, one REST call, or the website — each shown with a real Apple request and the real response it returns. The example pulls 41 fiscal years, from 1985 to 2025, in a single call.

8 min read · Updated

The part nobody warns you about

Ask any forum where to get thirty years of fundamentals and someone will tell you to scrape EDGAR, because the filings are free and public. They are. The recurring reply from people who have tried is less encouraging: EDGAR data is a nightmare, and the nightmare lasts about a year. Three specific things break.

  • Before fiscal 2009 there is no XBRL at all. The SEC phased structured filing data in from 2009. Older 10-Ks are HTML and plain text with no machine-readable tags, so the company-facts API simply has nothing to give you for the years that make a 30-year series a 30-year series.
  • The tags move underneath you. Revenue may be filed as Revenues in one year, SalesRevenueNet in another, and RevenueFromContractWithCustomerExcludingAssessedTax after the ASC 606 transition — or under a company-specific extension tag that exists in no taxonomy. A pull keyed on one tag name returns a series with silent gaps, and nothing raises an error to tell you.
  • Restatements rewrite the past. The FY2019 figure as it appeared in the FY2019 filing is not always the FY2019 figure carried in the FY2021 filing. If you want to know what was actually on the page when an investor read it, you need the first-disclosure date, not just the latest value.

None of that is unsolvable. It is just weeks of work that has nothing to do with whatever you were trying to analyse. The three routes below hand you the finished series instead.

RouteUse it whenSetup
MCPYou want to ask the assistant in plain language and have it fetch the data itselfOne command, or one JSON block
RESTYou are writing a script, a notebook or a pipelineOne POST, JSON in and JSON out
WebsiteYou want to read it, check a number, or export a CSV to paste inNo key needed to read

Route 1 — MCP, so the assistant fetches it itself

The Model Context Protocol lets an assistant call tools on a server you have connected. Once the EvidInvest server is connected, you ask a question in English and the model calls get_income_statement on its own — no copying, no pasting, and no risk of it inventing a figure because it had none.

Claude Code — one line

Terminal
claude mcp add --transport http evidinvest https://mcp.evidinvest.com/mcp \
  --header "Authorization: Bearer YOUR_API_KEY"

Claude Desktop and Cursor — one JSON block

Paste this into claude_desktop_config.json or .cursor/mcp.json and restart the client.

claude_desktop_config.json · .cursor/mcp.json
{
  "mcpServers": {
    "evidinvest": {
      "type": "streamable-http",
      "url": "https://mcp.evidinvest.com/mcp",
      "headers": { "Authorization": "Bearer YOUR_API_KEY" }
    }
  }
}

ChatGPT

ChatGPT reaches MCP servers through custom connectors, which require the server to authenticate the user with OAuth rather than an API key header. EvidInvest's OAuth support is being built; the one-click ChatGPT connector path will be documented on /developers when it is available. Until then, ChatGPT users get the same data through route 2 — the REST endpoint has a published OpenAPI 3.1 spec, which is what a custom GPT action consumes.

Then just ask

Prompt
Using the evidinvest tools, pull Apple's annual income statement
for every year available (limit 41) and tell me how revenue and net
margin changed between the first and last fiscal year on file.

The assistant calls get_income_statement with symbol=AAPL, period=annual, limit=41 and receives the same payload shown under route 2 — 41 periods, newest first, each with revenue, gross profit, operating income, EBITDA, net income, basic and diluted EPS, and the three margin percentages. From FY1985 at $1.92bn of revenue and a 3% net margin to FY2025 at $416.16bn and 27%, the model has the whole series in context and does not have to guess at any of it.

Route 2 — one REST call

Every MCP tool is also a plain HTTP endpoint at /v1/tools/<tool>, same key and same credit balance. The request body wraps the parameters in an arguments object; that wrapper is required.

curl
curl -s https://mcp.evidinvest.com/v1/tools/get_income_statement \
  -H "Authorization: Bearer $EVIDINVEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"arguments":{"symbol":"AAPL","period":"annual","limit":41}}'

Here is what actually comes back, captured on . It is the real response with the middle 39 fiscal years cut out for length; no field has been renamed and no value altered.

Response · AAPL · annual · 41 periods
{
  "symbol": "AAPL",
  "period": "annual",
  "periods_returned": 41,
  "periods": [
    {
      "date": "2025-09-27T00:00:00.000Z",
      "revenue": 416161000000,
      "gross_profit": 195201000000,
      "operating_income": 133050000000,
      "net_income": 112010000000,
      "eps_diluted": 7.46,
      "gross_margin_pct": 47,
      "net_margin_pct": 27,
      "filing_date": "2025-10-31",
      "accession": "0000320193-25-000079",
      "source_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/0000320193-25-000079-index.htm"
    },

    ... 39 fiscal years omitted ...

    {
      "date": "1985-09-30T00:00:00.000Z",
      "revenue": 1918300000,
      "gross_profit": 842300000,
      "operating_income": 147300000,
      "net_income": 61200000,
      "eps_diluted": 0,
      "gross_margin_pct": 44,
      "net_margin_pct": 3,
      "filing_date": "1985-09-30",
      "accession": null,
      "source_url": null
    }
  ],
  "attribution": {
    "fundamentals": "EvidInvest financial statements; SEC EDGAR-linked from fiscal 2009"
  }
}

Look at the last three keys on each row. The FY2025 row carries filing_date, accession and source_url — the 10-K those figures came from, openable on sec.gov. The FY1985 row carries the same three keys set to null. That is not a gap in the response; it is the response telling you which era a row belongs to, which the next section explains.

Forty-one fiscal years, one call, one credit. The same thing in Python:

Python
import os, requests

r = requests.post(
    "https://mcp.evidinvest.com/v1/tools/get_income_statement",
    headers={"Authorization": f"Bearer {os.environ['EVIDINVEST_API_KEY']}"},
    json={"arguments": {"symbol": "AAPL", "period": "annual", "limit": 41}},
    timeout=30,
)
r.raise_for_status()
rows = r.json()["periods"]        # 41 fiscal years, newest first
print(len(rows), rows[0]["date"][:10], rows[-1]["date"][:10])
# 41 2025-09-27 1985-09-30

Swap get_income_statement for get_balance_sheet or get_cash_flow for the other two statements. The full schema for all of them is in the OpenAPI 3.1 spec.

Route 3 — read it on the website, export a CSV

If you would rather look at the numbers first, or you want a file to attach to a chat, open evidinvest.com/financials/AAPL. Switch the period toggle to annual and the table footer reads Showing 1-6 of 41 periods, with arrows to page back through the rest — the same 41 fiscal years the API returns. The Download CSV button exports the statement tab you are on, every period included, one row per line item. Attach that file to ChatGPT or Claude and you have the series in context without any setup at all.

Reading the page costs nothing and needs no account. It is the fastest way to sanity-check that a company has the depth you need before you write any code against it.

Where each row comes from

A 40-year series is only useful if you know which parts of it you can trace. Two things are true of this one, and they are different things.

  • The XBRL era, for US listings:the row comes from the company's own filing — the 10-K or 10-Q, or the 20-F or 40-F for IFRS filers — and the row itself carries filing_date, accession and source_url. The filing named is the one where that fiscal year first appeared, not the most recent filing to restate it, so a later restatement does not silently overwrite what was originally disclosed. Because a 10-K carries two comparative years alongside the current one, this reaches slightly further back than the start of XBRL itself: on Apple, fiscal 2007 and 2008 both cite the FY2009 10-K, 0001193125-09-214859, which is the earliest filing either year appears in.
  • Earlier fiscal years:the row comes from EvidInvest's standardized statements archive, which covers the pre-XBRL era back to fiscal 1985. On those rows accession and source_url are null— deliberately, because there is no machine-readable filing to point at and inventing a link would be worse than admitting there isn't one. The figures are normalised onto the same schema as the filed years so the series is continuous, and the attribution field names the source.

So the null is the useful part. You can partition a 41-year series into “traceable to a filing” and “standardized history” with a single field test, in code or in a prompt, without knowing anything about EDGAR's rollout dates. Filter on accession !== null and you have the rows a regulator could check; keep the rest and you have the long-run shape.

What a citation actually looks like

Concretely, for the Apple FY2025 figures above. Open evidinvest.com/valuation/AAPL and under the per-share numbers the page names the filing they came from:

10-K FY2025 · fiscal year ended 2025-09-27 · filed 2025-10-31 · accession 0000320193-25-000079

which resolves to sec.gov/Archives/edgar/data/320193/000032019325000079/ — the filing itself, on the SEC's servers, not a copy of it.

The filing-search tools carry the same thing per passage rather than per company. A search_sec_filings result returns the exact filing text alongside citation: "AAPL 10-Q 2025-01-31 (Item 1)", accession_number: "0000320193-25-000008" and a source_url pointing at the document on sec.gov, so the sentence a model quotes can be opened and read in the original.

Why this matters more for a language model than for a person: a model handed a bare number has no way to distinguish a figure it retrieved from a figure it produced, and neither do you. A figure that arrives with its form, its period, its accession number and its sec.gov URL can be checked in one click, survives a restatement because the accession pins which filing it came from, and gives the model something to cite instead of something to paraphrase. It is the difference between an answer you can audit and an answer you have to trust.

This works the same way over REST and over MCP, on get_income_statement, get_balance_sheet and get_cash_flow alike — the citation is a property of the row, not of the transport or of one favoured endpoint.

Limits worth knowing before you build on it

  • Quarterly does not go as deep as annual. The quarterly series covers the same companies but stops well short of 1985. If your model needs quarterly data across decades, check the specific tickers first.
  • Depth varies by company. Apple returns 41 periods; a company that listed in 2014 returns eleven. More than 5,000 US-listed companies have 30 or more annual periods on file, which is the number that matters for a 30-year question, but it is not every ticker.
  • Listings outside the US are a different dataset. More than 40,000 of them across 60+ exchanges are covered, standardized by EvidInvest, with end-of-day prices. Those rows have no SEC filing behind them, no filing link, and shorter history than the US series.
  • Prices are delayed, not live. US prices are Cboe data, at least 15 minutes behind, and every price-bearing response says so in its attribution. This is a fundamentals dataset; it is not built for trading systems.
  • No analyst estimates. Everything returned is reported history. Forward numbers are yours to model.

Getting a key

Sign up with email, Google or GitHub — no card — and create a key at /settings/api-keys. The key is shown once, so copy it then. Your first key comes with 900 free API and MCP calls, which is enough to pull the full annual series for a few hundred companies before you decide anything. After that, usage draws on credit packs — Starter $10 for 360 credits, Plus $20 for 720 and Pro $59 for 2,000 — where one credit is ten API or MCP calls; AI analyses draw credits by the tokens they use. Credits never expire and there is nothing to cancel.

If you are still choosing a provider, the September 2026 comparison of financial data APIs puts nine of them side by side on exactly this criterion, with each vendor's stated history depth taken from their own pricing page and dated. The full tool catalogue lives on /developers.

Questions people ask

Why can I not just point the model at EDGAR?
You can, and for a single recent filing it is the right answer. It stops working the moment you want a series. EDGAR's structured company-facts data starts with XBRL in fiscal 2009; before that the filings are HTML and text with no machine-readable tags at all. Within the XBRL era the tags themselves move — a company retires Revenues for RevenueFromContractWithCustomerExcludingAssessedTax, or files the same line under a custom extension tag — so a naive pull produces a series with holes in it and no error. And every restatement rewrites history: the 2019 figure in the FY2021 filing is not always the 2019 figure in the FY2019 filing. Handling those three things properly is the work.
How many years actually come back?
It depends on the company. Apple returns 41 fiscal years. Across US-listed companies, more than 5,000 have 30 or more annual periods on file, and the archive starts at fiscal 1985. Ask for a limit larger than what exists and you get everything there is, not an error.
Do the numbers carry a source I can check?
Yes, on the row itself. Each statement row from the XBRL era carries filing_date, accession and source_url for the filing where that fiscal year first appeared — a 10-K or 10-Q, or a 20-F or 40-F for IFRS filers — so you can open the same figure on sec.gov. Rows from before that come from EvidInvest’s standardized statements archive and carry null for those three fields, because no machine-readable filing exists to link to.
Is quarterly history as deep as annual?
No. Quarterly statements are available for the same companies but do not reach as far back as the annual series; ask for period=quarterly with a large limit and take what returns. Annual is the series that goes to 1985.
Does this work for companies outside the US?
Partly. More than 40,000 listings outside the US on 60+ exchanges are covered, standardized by EvidInvest, with end-of-day prices. Those have no SEC filing behind them, no filing link, and less history than the US set. The 40-year depth described on this page is the US series.
What does it cost to try?
Nothing to start. Sign up with email, Google or GitHub — no card — and your first API key comes with 900 free API and MCP calls. After that, usage draws on credit packs: Starter $10 for 360 credits, Plus $20 for 720 credits and Pro $59 for 2,000 credits, where one credit is ten API or MCP calls; AI analyses draw credits by the tokens they use. Credits never expire and there is no subscription to cancel.

Figures on this page were captured on . EvidInvest never says buy or sell; it shows what the filings say and how each number was computed. Research, not investment advice. Claude, Cursor and ChatGPT are trademarks of their respective owners. EvidInvest is an independent product and is not affiliated with, sponsored by or endorsed by Anthropic, OpenAI or Anysphere.

EvidInvest is an independent research and information tool. Figures are calculated from public SEC filings and third-party market data and are provided for informational and educational purposes only. EvidInvest does not provide investment advice, brokerage, or financial services, and is not affiliated with any company it covers. Verify all figures against primary sources before making any decision.