Blog/Finance and markets
5 min read

Simply Wall St API: Pull Stock Fundamentals by Ticker

Simply Wall St has no public API. Pull income statements, ratios and filings for any ticker through one key, billed per call, and read the TTM trap first.

Simply Wall St API: Pull Stock Fundamentals by Ticker

Get a company's income statement, ratios and filings by ticker in one prompt. Paste this into your agent:

Set up https://monid.ai/SKILL.md, and then use Monid to pull the income statement for NVDA, drop the TTM column, and give me a table with fiscal year, revenue, gross profit and net income.

One prompt pulls the statement behind a company page. 1 min setup · 30-60 hrs saved.

You opened the network tab on a Simply Wall St company page, saw GraphQL requests carrying the numbers behind the charts, and now you want those numbers in a script or a spreadsheet for a list of tickers. This guide covers the plain route: how to pull income statements, ratios and filings by ticker, what each response contains (we ran it live on 2026-10-16), and the traps that produce a wrong number without any error. It runs through Monid, the OpenRouter for agent tools: one key, one balance, every tool priced per call.

Is there a Simply Wall St API, and how do you get the same data?

There is no public Simply Wall St API: its home page, read on 2026-10-16, links no API, developer documentation or data export. The easier way to get the same kind of numbers is Monid. Install it once, add a key, and your agent calls fundamentals endpoints with no portal, no plan and no vendor account to set up.

  • Pay per call. Each call is billed on its own, at $0.01 for the income statement and the same for the statistics and filings endpoints (Verified 2026-10-16 on the StockAnalysis tools page). Buy calls as you need them: no monthly plan and no minimum top-up. Discovery and inspection are free; only a run bills.
  • One install, every API. The same key and balance call these endpoints and every other tool on Monid, so a second data source is a second command, not a second account.
  • Lives inside your agent. Install the CLI, add your key, run the prompt above, and the tools are there whenever your agent needs them, on demand, with nothing to keep running. Your agent reads SKILL.md and learns the rest, so setup is about a minute.

At that price a 20-ticker income-statement sweep is 20 calls, about $0.20 (Verified 2026-10-16).

How do you pull fundamentals for a list of tickers?

Run one call per ticker and the parameter is symbol. Discovery costs nothing, and a ticker list is just a loop.

For agents

Grab an API key at app.monid.ai, then paste this to your agent and hand it the key:

set up https://monid.ai/SKILL.md

It learns the whole discover, inspect, run workflow itself. More in the agent quickstart.

For humans

npm install -g @monid-ai/cli
monid keys add -k <your-api-key> -l main

Pull the income statement

monid run -p stockanalysis -e /get_stock_financials_income --query '{"symbol": "NVDA"}'

The response holds a financialData object with six periods. If you pass ticker instead of symbol, the call fails with a 422 that says Parameter 'symbol' is required. That is the good kind of failure: it names the field, and on 2026-10-16 it was not billed.

Pull the statistics for ratios and position

monid run -p stockanalysis -e /get_stock_statistics --query '{"symbol": "NVDA"}'

This gives you the derived measures (valuation, ratios, margins, cash flow) without computing them from the statements yourself.

Pull the filings behind the numbers

monid run -p nasdaq -e /get_stock_sec_filings --query '{"symbol": "NVDA", "limit": 3}'

This returns links to the annual report, the latest quarterly report and recent insider forms, so you can check a figure against the primary document.

Loop it over your tickers

Put one ticker per line in tickers.txt, then run:

mkdir -p out
while read -r t; do
  monid run -p stockanalysis -e /get_stock_financials_income \
    --query "{\"symbol\":\"$t\"}" > "out/$t.json"
done < tickers.txt

Each ticker writes one file. If you would rather not write the loop, hand the whole job to an agent:

Give this to your agent

$Set up https://monid.ai/SKILL.md, and then use Monid to pull the income statement for each ticker on this list, drop the TTM column, and give me one table with ticker, fiscal year, revenue and net income.

Can you call the Simply Wall St GraphQL endpoint yourself?

You can send the request, but it is a poor thing to build on. The GraphQL calls you see in devtools are the site's own interface between its web client and its backend. They are not a documented product, so nothing promises that the schema, the field names or the access rules stay the same when the site ships a new frontend.

What breaks

A script written against an interface like that fails on the owner's release schedule, not yours, and it often fails by returning a changed shape rather than an error. You find out from a wrong number in a report.

The rules side

What to do instead

Use a source whose product is the data, and check that it tells you where the numbers came from. The statistics response used here names its source and a timestamp, which the section on freshness below shows.

What do the fundamentals look like, and what can you build?

Three kinds of record: the statement, the statistics and the filing list. We ran all three for NVDA on 2026-10-16, so the fields below are what came back.

The income statement

The financialData object has 41 keys: three period labels and 38 metrics, each an array parallel to datekey. It is column-oriented, like a statement printed on a page, with line items down the side and periods across the top:

{
  "datekey":    ["TTM", "2026-01-25", "2025-01-26", "2024-01-28", "2023-01-29", "2022-01-30"],
  "fiscalYear": ["2027", "2026", "2025", "2024", "2023", "2022"],
  "revenue":    [302970000000, 215938000000, 130497000000, 60922000000, 26974000000, 26914000000],
  "netinc":     [192880000000, 120067000000, 72880000000, 29760000000, 4368000000, 9752000000]
}

Beyond revenue and net income the arrays include cor, gp, sgna, rnd, opex, opinc, pretax, taxexp, sharesDiluted, epsdil, fcf, ebitda and a set of margins such as grossMargin and operatingMargin. A few arrays came back all null for this company (currencyGains, advertisingExpenses, otherUnusualItems), so test for null before you do arithmetic. The response also carries a map of display titles, a source of spg and an availableSources list of four.

The statistics

Twenty top-level keys: a trust block plus 19 sections, among them valuation, ratios, evRatios, financialPosition, margins, cashFlow, dividends and stockSplits. Each section has a one-sentence text and a data list of entries with id, title, value and hover, where value is a display string like 5.17T and hover holds the exact figure. Four fairValue entries came back with value: null and proOnly: true, which means that part of the page is not in the data.

The filings

The filings call returned totalRecords: 72, the latest annual and quarterly report links, and three filing rows with HTML, DOC, PDF and XLS links.

What you can build with it

  • A peer table. Pull the same statement for a list of tickers, keep the fiscal-year rows, and compare revenue, margins and share counts side by side.
  • A screening sheet. Pull the statistics for a watchlist and keep a column per ratio you care about, refreshed on a schedule.
  • A source-checked dataset. Store a filing link next to each figure so every number can be traced to a document. For the insider-form side of the filing list, pulling SEC Form 4 data for any company has the full field list.

For private companies, where there are no quarterly statements to pull, the comparable record is funding rounds: PitchBook API: Get Funding Round Data Without a Seat shows that pull.

What goes wrong when you pull fundamentals?

Four things hide until you run more than one ticker, and the first one produces a wrong number from correct data.

Why is revenue0 not last year's revenue?

Because the first column is trailing twelve months. In the NVDA response revenue[0] is 302,970,000,000 and the label in datekey[0] is TTM. Fiscal 2026 is revenue[1], 215,938,000,000. Both numbers are right. Reading index 0 as the latest annual figure puts a trailing figure into an annual series, and for a growing company it looks like growth, not like a bug.

Index by label, never by position:

i = data["datekey"].index("2026-01-25")
revenue_fy26 = data["revenue"][i]

Or drop the TTM column first:

keep = [i for i, d in enumerate(data["datekey"]) if d != "TTM"]

Converting once at the boundary is usually worth it, because after that every filter, sort and join works like the rest of your code:

rows = [
    {k: v[i] for k, v in data.items() if isinstance(v, list)}
    for i in range(len(data["datekey"]))
]

Why did I get six periods when ten exist?

The response carried full_count: 10 while returning six periods, five fiscal years plus TTM. If you build a long-run series, treat the shorter array as a ceiling you hit, not as the company's whole history, or your chart starts in the wrong year.

Why does the fiscal year not match the calendar year?

NVDA's fiscal year runs February to January (details.fiscalYear said "February - January"), so the period ending 2026-01-25 is labelled fiscal 2026 while the TTM column is labelled 2027. Compare companies by datekey when you want calendar alignment and by fiscalYear when you want each company's own reporting. Mixing them across a peer group is an invisible error.

Why are some arrays all null?

Because a line item that does not apply to a company comes back as an array of nulls, not as a missing key. Check for null before you sum or divide.

How do you know whether a financial number is current?

You read the trust block, and the reason it deserves a section is that most financial sources give you no metadata at all.

What came back

Both stockanalysis responses carried a trust object. On the statistics call:

{
  "sources": [{ "name": "S&P Global Market Intelligence", "short": "S&P Global" }],
  "freshnessLag": "hours",
  "updateFrequency": "daily",
  "lastUpdated": 1792168739575
}

That timestamp is epoch milliseconds, 2026-10-16T16:38:59Z, the day of the call. On the income-statement call the same block said updateFrequency: "quarterly" and lastUpdated: "2026-08-26", a date string. The filing list shows why: the latest 10-Q was filed on 2026-08-26.

Why this matters more than the numbers

A figure without a date and a source cannot be checked. With provenance you can tell a stale cache from a company that simply has not reported, and you can tell whether two numbers come from the same upstream. Note also that the two endpoints use different formats for lastUpdated, so normalise it when you store it.

What to do with it

Store lastUpdated and the source name next to every figure you persist, and alert when the value stops moving for longer than the update frequency says it should. A frozen source looks exactly like a quiet market, and the timestamp is the only thing that separates them. Dropping the field at the parse step turns a checkable number into one you can only trust.

Which endpoint should I use for which job?

EndpointWhat it doesInputReturnsBillingPrice (Verified 2026-10-16)
stockanalysis/get_stock_financials_incomeIncome statement by periodsymbol41 keys, six periods, column-orientedPer call$0.01
stockanalysis/get_stock_statisticsRatios and positionsymbol19 sections plus trustPer call$0.01
nasdaq/get_stock_sec_filingsFiling linkssymbol, limitLatest 10-K and 10-Q plus filing rowsPer call$0.01

Every row was run on 2026-10-16 and priced with monid inspect the same day. Current figures are on monid.ai/tools.

Use the income statement for a series over time, the statistics for a snapshot of ratios, and the filings when a number looks wrong, because a filing is the primary document and one call settles the question.

When is another route a better fit?

You are trading on it. Execution needs exchange-licensed real-time data with a latency guarantee, and these endpoints are for research. The freshnessLag label is the provider describing itself, not a service level.

You publish figures to customers. Redistribution is what market data licences govern, and rules differ by country and by use. If your product shows financials to paying users, check the licence and the rules where you operate before you ship.

You need point-in-time history. Statements get restated, and most sources show today's version of the past. Backtesting on restated history uses numbers nobody had at the time. Point-in-time databases exist for this and are priced for it.

You need every field for every company. The income statement returned arrays of nulls for lines that do not apply, and part of the statistics page came back as proOnly nulls. Sample your own universe first.

We resell these endpoints, and the first lesson in this post, index by label, is a one-line fix whoever supplies the data.

Conclusion

The way to get Simply Wall St-style fundamentals in code is one call per ticker through Monid: $0.01 a call (Verified 2026-10-16), one key for this and every other tool, about a minute to set up, ready inside your agent whenever you need it. There is no public Simply Wall St API to use instead, and an interface meant for its own web client is not a base for a pipeline.

Two things matter more than the choice of source. The first column is TTM, not the latest fiscal year, so index by label and never by position. And the trust block tells you who supplied each number and when, so keep it next to the figure.

How we estimated the time saved: sourcing statements from a vendor or from filings, normalising the column layout, and keeping the pipeline running is roughly 10 to 20 hours each, so three tasks of that kind are 30 to 60 hours. The 1 minute is the install, key and first call once you already have a Monid key.

Free next step: run monid inspect -p stockanalysis -e /get_stock_financials_income, make one call for a ticker you know, and print datekey next to revenue. The TTM column shows up immediately.

FAQ

Is there a free Simply Wall St API?

No, there is no public Simply Wall St API, free or paid. For the same kind of data through Monid, each income-statement, statistics or filings call costs $0.01 (Verified 2026-10-16), with no monthly plan and no minimum, and discovery and inspection cost nothing.

Can you use an internal GraphQL endpoint you found in devtools?

You can send the request, but it is a bad foundation. It is the site's own interface, so the schema can change with any frontend release and access can be tightened at any time. Terms and rules also differ by site and by country, so read them before you pull from an interface that was not offered to you.

Why does the fiscal year not match the calendar year?

Many companies close their books on a date that suits their business. In the NVDA response the periods end in late January and the fiscalYear labels run a year ahead of the datekey dates, so the period ending 2026-01-25 is fiscal 2026. Compare by datekey for calendar alignment and by fiscalYear to match a company's own reporting.

Why do historical financials change between pulls?

Restatements. Companies revise prior periods for corrections, discontinued operations and acquisitions, and most sources overwrite history with the current version. Store each figure with the date you retrieved it so you can detect a change. If your analysis depends on what was known at the time, you need a point-in-time source.

Does coverage extend beyond US listings?

Test it rather than assume it. The check costs one call: pull a ticker from each market you care about and look at whether datekey and full_count are populated to the depth you need. Do that before you design a schema around the answer.

Published September 2026.

simply wall st apisimply wall st graphqlstock fundamentals apiincome statement apifinancial data