Examples
Each example uses call and frame from the Python quick start. The output is what the code printed against the current data build.
Find a metric
Metrics are named by id: revenue or net_income for the statements, kpi.… for figures a company reports itself. There are about 82,000, so look ids up rather than guessing. The most widely reported match is usually the standard one.
result = call("search_metrics", query="same store sales", limit=5)
print(frame(result)[["metric_id", "companies_reporting"]])
metric_id companies_reporting
0 kpi.same_store_sales_growth_pct 59
1 kpi.consolidated_same_store_sales_growth_pct 4
2 kpi.same_store_sales_pct 4
3 kpi.domestic_same_store_sales_growth_pct 3
4 kpi.system_wide_same_store_sales_growth_pct 3
Compare companies
One metric for up to 25 companies. Annual revenue in billions for Apple, Amazon and Alphabet:
result = call("compare_companies", tickers=["AAPL", "AMZN", "GOOGL"], metric_id="revenue",
fy_from=2021)
df = frame(result)
print(df.pivot(index="fiscal_year", columns="ticker", values="value").div(1e9).round(1))
ticker AAPL AMZN GOOGL
fiscal_year
2021 365.8 469.8 257.6
2022 394.3 514.0 282.8
2023 383.3 574.8 307.4
2024 391.0 638.0 350.0
2025 416.2 716.9 402.8
Fiscal years follow each company's own calendar: Apple's ends in September, Amazon's and Alphabet's in December. To line up quarters across companies, use the calendar_year and calendar_quarter columns instead.
Guidance against the result
What HubSpot guided for fiscal 2025 revenue, and how it came out:
result = call("get_guidance", ticker="HUBS", metric="revenue", target_period="FY2025")
df = frame(result)
guide = df[(df.metric_id == "guid.revenue") & (df.target_period == "FY2025")]
columns = ["issued_in", "guidance_low", "guidance_high", "reported_actual", "actual_vs_guidance"]
print(guide[columns].T)
1
issued_in Earnings release for fiscal 2025 Q3
guidance_low 3113000000.0
guidance_high 3115000000.0
reported_actual 3131266000.0
actual_vs_guidance above
By default you get the latest guide for each metric and period; include_revisions=True returns every revision.
Calculations in SQL
run_sql takes one read-only DuckDB query over the Stock Atlas tables. Amazon's net margin, year by year:
sql = """
SELECT fy AS fiscal_year,
max(value) FILTER (WHERE metric_id = 'revenue') / 1e9 AS revenue_bn,
max(value) FILTER (WHERE metric_id = 'net_income') / 1e9 AS net_income_bn,
round(100 * net_income_bn / revenue_bn, 1) AS net_margin_pct
FROM obs
WHERE ticker = 'AMZN' AND ptype = 'FY' AND fy BETWEEN 2021 AND 2025
GROUP BY fy
ORDER BY fy
"""
print(frame(call("run_sql", sql=sql)).round(1))
fiscal_year revenue_bn net_income_bn net_margin_pct
0 2021 469.8 33.4 7.1
1 2022 514.0 -2.7 -0.5
2 2023 574.8 30.4 5.3
3 2024 638.0 59.2 9.3
4 2025 716.9 77.7 10.8
Prices
Daily prices are in the prices table. Each stock's return over 2025, from the first close to the last:
sql = """
SELECT ticker,
arg_min(close, d) AS first_close,
arg_max(close, d) AS last_close,
round(100 * (last_close / first_close - 1), 1) AS return_pct
FROM prices
WHERE ticker IN ('AAPL', 'AMZN', 'GOOGL', 'META', 'MSFT', 'NVDA', 'TSLA')
AND d BETWEEN '2025-01-01' AND '2025-12-31'
GROUP BY ticker
ORDER BY return_pct DESC
"""
print(frame(call("run_sql", sql=sql)))
ticker first_close last_close return_pct
0 GOOGL 189.41 312.89 65.2
1 NVDA 138.32 186.43 34.8
2 TSLA 379.49 449.94 18.6
3 MSFT 418.60 483.62 15.5
4 AAPL 243.82 272.19 11.6
5 META 599.24 659.72 10.1
6 AMZN 220.21 230.82 4.8
Price data is provided for free by IEX; a query that reads it returns the attribution in its attribution field.
Asking Claude
Connected to Claude, you ask in plain English and Claude chooses the tools. For example:
- “Show Apple's annual revenue for the last five fiscal years, with the 10-K for each.” —
get_financials - “Compare comparable store sales growth for O'Reilly and Advance Auto Parts since 2024.” —
search_metrics,compare_companies - “What revenue guidance did HubSpot give for 2025, how did it change, and how did they do?” —
get_guidance - “Where did that number come from?” —
get_provenance