Seven endpoints. Install, query, done. Everything you need to integrate xfinlink into a research pipeline, trading system, or weekend project.
Install the package, set your API key, and make your first query in under a minute.
pip install xfinlink
Create a free account to get your API key, then:
import xfinlink as xfl # Set your API key — get a free key at https://xfinlink.com/signup xfl.set_api_key("YOUR_API_KEY") # Historical prices prices = xfl.prices("AAPL", start="2024-01-01") # Financial statements fundamentals = xfl.fundamentals("AAPL", period_type="annual") # Pre-computed metrics (P/E, ROE, margins, ...) metrics = xfl.metrics("AAPL", period_type="ttm", fields=["valuation", "scores"]) # Index constituents sp500 = xfl.index("sp500") # Search for entities results = xfl.search(q="apple") # Entity resolution (handles ticker recycling) entity = xfl.resolve("GM")
Use an API key via the X-API-Key header for full access (the Python client handles this automatically).
Most API requests require an API key. Create a free account to get yours. Search and resolve allow restricted unauthenticated calls; use a key for normal limits and full detail.
Pass the key via the X-API-Key header:
curl -H "X-API-Key: your-api-key" \
https://api.xfinlink.com/v1/prices/AAPL?start=2024-01-01The Python client handles auth automatically:
import xfinlink as xfl # Set your API key — get a free key at https://xfinlink.com/signup xfl.set_api_key("YOUR_API_KEY")
Your API key is shown on the dashboard after sign-up. You can regenerate it at any time.
OHLCV prices with split adjustment, total returns, and dividend/split event data. Coverage back to 1996 for every US-listed stock and ETF. Supports daily through yearly aggregation intervals.
| param | type | default | description |
|---|---|---|---|
| ticker | str | list[str] | required | Ticker(s) to fetch. |
| start | str (ISO date) | optional | Earliest date, inclusive. |
| end | str (ISO date) | optional | Latest date, inclusive. Defaults to today. |
| interval | str | "1d" | Aggregation interval: 1d, 3d, 1w, 1mo, 3mo, 6mo, 1y. |
| fields | list[str] | optional | Subset of columns. Defaults to 11 fields; market_cap is opt-in. |
| adjust | str | "split" | Adjustment mode: split (default) or none. |
Request:
df = xfl.prices("AAPL", start="2024-01-01", fields=["close", "volume"])
Response:
date ticker close volume 2024-01-02 AAPL 185.64 45,123,456 2024-01-03 AAPL 184.25 42,889,012 2024-01-04 AAPL 181.91 49,301,234 ...
Reported financials — income statement, balance sheet, cash flow — back to 1950 for most listed US companies.
| param | type | default | description |
|---|---|---|---|
| ticker | str | list[str] | required | Ticker(s) to fetch. |
| period_type | str | "all" | "annual" | "quarterly" | "all" |
| fields | list[str] | optional | Subset of 147 available fields. |
| include | str | optional | "segments" — adds revenue breakdowns by geography, product, and business segment. |
| segment_members | str | "primary" | "primary" or "all". Primary returns segments summing to revenue; all includes subtotals. |
| start | str (ISO date) | optional | Earliest period_end. |
| end | str (ISO date) | optional | Latest period_end. |
| fiscal_year | int | optional | Exact-match filter on fiscal_year (e.g. 2023). Invalid values emit a warning and are ignored. |
| period_end | str (ISO date) | optional | Exact-match filter on period_end (e.g. 2023-09-30). Invalid values emit a warning and are ignored. |
df = xfl.fundamentals("AAPL", period_type="annual", fields=["revenue", "net_income"]) # With revenue segments df = xfl.fundamentals("AAPL", include_segments=True)
Full entity history for a ticker. Every company that ever used this ticker, with validity dates, classifications, and index membership.
| param | type | default | description |
|---|---|---|---|
| ticker | str | required | Ticker symbol or comma-separated tickers (up to 10). |
| include | str | optional | index, classifications |
info = xfl.resolve("GM") for entity in info["data"]["GM"]["entities"]: print(entity["name"], entity["ticker_valid_from"], entity["ticker_valid_to"])
Discover entities by name, sector, type, or classification code.
| param | type | default | description |
|---|---|---|---|
| q | str | optional | Fuzzy search on name or ticker. |
| gics_sector | str | optional | Filter by GICS sector name. |
| entity_type | str | optional | Filter by entity type (corporation, etc.). |
| sic | str | optional | Filter by SIC code. |
| naics | str | optional | Filter by NAICS code. |
| country | str | US | Country filter. |
| limit | int | 50 | Results per page (max 500). |
| offset | int | 0 | Pagination offset. |
df = xfl.search(gics_sector="Consumer Staples") df = xfl.search(q="apple")
Current and historical index constituents. Available indices: sp500, ndx100, djia, russell2000.
| param | type | default | description |
|---|---|---|---|
| index_name | str | sp500 | Index name (path parameter). |
| as_of | str (ISO date) | today | Point-in-time membership date. |
| limit | int | 500 | Results per page (max 1000). |
| offset | int | 0 | Pagination offset. |
df = xfl.index("sp500") df = xfl.index("sp500", as_of="2020-01-01")
Insider transactions from SEC Form 3, 4, and 5 filings. One row per transaction. Shares and prices are split-adjusted. Coverage 1986 to present. Pro tier only; free-tier keys receive 402.
| param | type | default | description |
|---|---|---|---|
| ticker | str | required | Ticker or comma-separated tickers (up to 100). |
| start | str (ISO date) | 1y ago | Earliest transaction_date. |
| end | str (ISO date) | optional | Latest transaction_date. |
| transaction_type | str | optional | Decoded type, e.g. open_market_buy, open_market_sell, grant_or_award, option_exercise, tax_withholding, gift. Comma-separated for multiple. |
| acquisition_or_disposition | str | optional | "A" or "D". |
| ownership_type | str | optional | "direct" or "indirect". |
| form_type | str | optional | "3", "4", "5" (or amended e.g. "4/A"). |
| insider_role | str | optional | Substring match on role (CEO, CFO, Director, etc.). |
| insider_name | str | optional | Substring match on name. |
| min_value | num | optional | Minimum transaction_value in dollars. |
| include_amendments | bool | false | Include amendment rows. |
| limit | int | 1000 | Rows per page, max 5000. |
Fields returned: entity_id, ticker, entity_name, transaction_date, filing_date, form_type, insider_name, insider_role, insider_role_other, transaction_code, transaction_type, acquisition_or_disposition, shares, shares_held_after, transaction_price, transaction_value, ownership_type, is_amendment, document_id, sequence_in_filing, data_quality.
df = xfl.insiders("TSLA", transaction_type="open_market_sell", insider_role="CEO")
108 pre-computed financial metrics across 9 categories. All ratios as decimals (0.46 = 46%). Market cap and enterprise value in millions USD. Per-share values in dollars.
| param | type | default | description |
|---|---|---|---|
| ticker | str | required | Ticker or comma-separated tickers (max 100). |
| period_type | str | annual | annual, quarterly, ttm (trailing 12-month snapshot), or daily (one row per trading day). |
| fields | str | all | Comma-separated metric names or category names: valuation, profitability, leverage, liquidity, efficiency, per_share, dividends, scores, growth. |
| growth_basis | str | yoy | Growth comparison: yoy (year-over-year), qoq (quarter-over-quarter), or ttm_yoy. |
| start | str (ISO date) | optional | Start date. Daily mode defaults to 90 days ago. |
| end | str (ISO date) | optional | End date for period_end. |
| limit | int | 20 | Rows per page (max 100). |
| field | formula |
|---|---|
| market_cap | close price x shares_outstanding |
| market_cap_diluted | close price x weighted_avg_shares_diluted |
| enterprise_value | market_cap + total_debt - cash |
| pe_ratio | close price / diluted EPS (TTM) |
| ps_ratio | market_cap / revenue (TTM) |
| pb_ratio | market_cap / total_equity |
| price_to_cash_flow | market_cap / operating_cash_flow (TTM) |
| ev_ebitda | enterprise_value / EBITDA (TTM) |
| ev_ebit | enterprise_value / EBIT (TTM) |
| ev_revenue | enterprise_value / revenue (TTM) |
| ev_gross_profit | enterprise_value / gross_profit (TTM) |
| price_to_fcf | market_cap / free_cash_flow (TTM) |
| price_to_tangible_book | market_cap / (total_equity - goodwill - intangibles) |
| price_to_cash | market_cap / cash_and_short_term_investments |
| price_to_net_working_capital | market_cap / (current_assets - current_liabilities) |
| tobins_q | market_cap / total_assets |
| grahams_number | sqrt(22.5 x EPS_diluted x book_value_per_share) |
| peg_ratio | P/E ratio / EPS growth rate |
| earnings_yield | net_income (TTM) / market_cap |
| dividend_yield | (DPS x shares) TTM / market_cap |
| field | formula |
|---|---|
| gross_margin | gross_profit / revenue |
| operating_margin | operating_income / revenue |
| net_margin | net_income / revenue |
| ebitda_margin | EBITDA / revenue |
| fcf_margin | free_cash_flow / revenue |
| pretax_margin | pretax_income / revenue |
| roe | net_income / total_equity |
| roa | net_income / total_assets |
| roic | (net_income + interest_expense x 0.79) / (total_equity + long_term_debt) |
| return_on_tangible_assets | net_income / avg(total_assets - goodwill - intangibles) |
| return_on_tangible_equity | net_income / avg(total_equity - goodwill - intangibles) |
| return_on_common_equity | (net_income - preferred_dividends) / avg(total_equity - preferred_equity) |
| roe_adjusted_to_book | ROE / price_to_book |
| return_on_total_capital | operating_income / avg(equity + debt + minority_interest) |
| return_on_capital_employed | operating_income / avg(total_assets - current_liabilities) |
| operating_earnings_yield | operating_income (TTM) / market_cap |
| field | formula |
|---|---|
| debt_to_equity | total_debt / total_equity |
| debt_to_assets | total_debt / total_assets |
| long_term_debt_to_equity | long_term_debt / total_equity |
| long_term_debt_to_assets | long_term_debt / total_assets |
| debt_to_ebitda | total_debt / EBITDA (TTM) |
| debt_to_revenue | total_debt / revenue (TTM) |
| net_debt_to_ebitda | (total_debt - cash) / EBITDA (TTM) |
| equity_to_assets | total_equity / total_assets |
| assets_to_equity | total_assets / total_equity |
| total_debt_to_capital | total_debt / (total_equity + total_debt) |
| cash_to_debt | cash_and_short_term_investments / total_debt |
| effective_interest_rate | interest_expense / avg(total_debt) |
| interest_coverage | EBIT / interest_expense |
| ebitda_interest_coverage | EBITDA / interest_expense |
| ebitda_less_capex_interest_coverage | (EBITDA - |capex|) / interest_expense |
| goodwill_to_assets | goodwill / total_assets |
| tangible_common_equity_ratio | (equity - goodwill - intangibles - preferred) / (assets - goodwill - intangibles) |
| field | formula |
|---|---|
| current_ratio | current_assets / current_liabilities |
| quick_ratio | (current_assets - inventory) / current_liabilities |
| cash_ratio | cash_and_short_term_investments / current_liabilities |
| cash_conversion_cycle | days_inventory + days_sales_outstanding - days_payable |
| field | formula |
|---|---|
| asset_turnover | revenue / total_assets |
| inventory_turnover | cost_of_revenue / inventory |
| cogs_to_revenue | cost_of_revenue / revenue |
| inventory_to_revenue | inventory / revenue |
| days_inventory | inventory / cost_of_revenue x days_in_period |
| days_payable | accounts_payable / cost_of_revenue x days_in_period |
| days_sales_outstanding | accounts_receivable / revenue x days_in_period |
| total_receivables_turnover | revenue / accounts_receivable |
| fixed_assets_turnover | revenue / net_PP&E |
| rd_to_revenue | research_and_development / revenue |
| sga_ratio | selling_general_admin / revenue |
| field | formula |
|---|---|
| revenue_per_share | revenue / shares_outstanding |
| book_value_per_share | total_equity / shares_outstanding |
| tangible_book_value_per_share | (total_equity - goodwill - intangibles) / shares_outstanding |
| cash_per_share | cash_and_equivalents / shares_outstanding |
| debt_per_share | total_debt / shares_outstanding |
| ocf_per_share | operating_cash_flow / shares_outstanding |
| fcf_per_share | free_cash_flow / shares_outstanding |
| ebit_per_share | EBIT / shares_outstanding |
| ebitda_per_share | EBITDA / shares_outstanding |
| capex_per_share | capital_expenditures / shares_outstanding |
| working_capital_per_share | (current_assets - current_liabilities) / shares_outstanding |
| ncavps | (current_assets - total_liabilities - preferred_equity) / shares_outstanding |
| field | formula |
|---|---|
| dividend_payout_ratio | dividends_per_share / EPS_diluted |
| buyback_yield | (share_repurchases - share_issuance) / market_cap |
| shares_buyback_ratio | (prior_shares - current_shares) / prior_shares |
| sustainable_growth_rate | ROE x (1 - dividend_payout_ratio) |
| cash_dividend_coverage | operating_cash_flow / |dividends_paid| |
| field | formula |
|---|---|
| accruals | net_income - operating_cash_flow |
| quality_ratio | gross_profit / total_assets |
| gross_profit_to_assets | gross_profit / avg(total_assets) |
| sloan_ratio | (net_income - OCF - investing_CF) / total_assets |
| altman_z_score | 1.2(WC/A) + 1.4(RE/A) + 3.3(EBIT/A) + 0.6(MC/L) + 1.0(Rev/A) |
| piotroski_f_score | Sum of 9 binary tests: profitability (4), leverage (3), efficiency (2) |
| beneish_m_score | 8-ratio model (DSRI, GMI, AQI, SGI, DEPI, SGAI, LVGI, TATA) |
| springate_score | 1.03A + 3.07B + 0.66C + 0.4D |
| zmijewski_score | -4.336 - 4.513(NI/A) + 5.679(TL/A) + 0.004(CA/CL) |
| fulmer_h_factor | 9-variable model including log(tangible assets), log(EBIT/interest) |
| kz_index | 5-variable model of cash flow, Q, leverage, dividends, cash |
| field | formula |
|---|---|
| revenue_growth | (current - prior) / |prior|. TTM-to-TTM in ttm/daily modes |
| net_income_growth | (current - prior) / |prior| |
| eps_diluted_growth | (current - prior) / |prior| |
| eps_basic_growth | (current - prior) / |prior| |
| ebitda_growth | (current - prior) / |prior| |
| gross_profit_growth | (current - prior) / |prior| |
| fcf_growth | (current - prior) / |prior| |
| total_assets_growth | (current - prior) / |prior| (balance sheet) |
| total_debt_growth | (current - prior) / |prior| (balance sheet) |
| capex_growth | (current - prior) / |prior| |
| dps_growth | (current - prior) / |prior| |
| market_cap_performance | (current_mcap - prior_mcap) / |prior_mcap| |
# Annual valuation + profitability df = xfl.metrics("AAPL", fields=["valuation", "profitability"]) # TTM snapshot with all financial scores df = xfl.metrics("AAPL", period_type="ttm", fields=["scores"]) # Daily P/E for the last 90 days df = xfl.metrics("AAPL", period_type="daily", fields=["pe_ratio", "market_cap"]) # Year-over-year growth df = xfl.metrics("AAPL", fields=["growth"], growth_basis="yoy")
230+ data fields across seven endpoints. See the Explorer on the home page for live values.
INCOME STATEMENT (38)
BALANCE SHEET — ASSETS (23)
BALANCE SHEET — LIABILITIES (19)
BALANCE SHEET — EQUITY (10)
CASH FLOW (33)
SHARES & CLASSIFICATION (7)
Convention: as-filed. Share count fields are returned as the company reported them on the filing date — not retroactively split-adjusted. To derive split-adjusted shares for a period, multiply by the cumulative product of split_ratio from /v1/prices for all splits after period_end.
INDUSTRY — BANKING (9) • INSURANCE (5) • REIT (3)
VALUATION (20)
PROFITABILITY (16)
LEVERAGE (17)
LIQUIDITY (4)
EFFICIENCY (11)
PER-SHARE (12)
DIVIDENDS (5)
SCORES (11)
GROWTH (12)
xfinlink follows the academic convention for price data. This matters for backtesting and returns analysis.
| field | description |
|---|---|
| close | Raw unadjusted closing price — what actually traded on the exchange that day. |
| adj_close | Split-only adjusted close. Adjusted for stock splits but NOT for dividends. Comparable across split events. |
| return_daily | Total daily return including dividends. Use this for performance analysis and backtesting. |
| dividend | Cash dividend amount on ex-date. Zero on non-dividend days. |
| split_ratio | Split ratio on split date (e.g., 4.0 for a 4:1 split). 1.0 on non-split days. |
Adjustment direction: adj_close is split-only backward-adjusted to the current post-split share basis. To derive a forward-adjusted series from an anchor date, request raw close plus split_ratio, then compound split ratios forward.
import xfinlink as xfl df = xfl.prices("AAPL", start="2020-08-27", end="2020-09-02", fields=["close", "split_ratio"], adjust="none") df = df.sort_values("date") factor = df["split_ratio"].fillna(1.0).cumprod() df["forward_adj_close"] = df["close"] * factor
date ticker close split_ratio forward_adj_close 2020-08-27 AAPL 500.04001 NaN 500.04001 2020-08-28 AAPL 499.23001 NaN 499.23001 2020-08-31 AAPL 129.03999 4.0 516.15996 2020-09-01 AAPL 134.17999 NaN 536.71996 2020-09-02 AAPL 131.39999 NaN 525.59996
Why no dividend-adjusted prices? Dividend-adjusted prices retroactively change every time a company pays a dividend, making historical values unstable. xfinlink stores stable values (split-only adjusted) plus total returns, which is the academic standard for quantitative research.
How to compute dividend-adjusted prices client-side:
import xfinlink as xfl df = xfl.prices("AAPL", start="2020-01-01", fields=["adj_close", "return_daily"]) # Build cumulative total return index df["total_return_index"] = (1 + df["return_daily"]).cumprod() # Derive dividend-adjusted price series df["div_adj_close"] = df["adj_close"].iloc[-1] * df["total_return_index"] / df["total_return_index"].iloc[-1]
Price fields and fundamentals fields are on different split-adjustment bases.
adj_close is split-only adjusted (no dividend adjustment). All fundamentals per-share fields (eps_diluted, dividends_per_share) are as-reported with no split adjustment. Do not combine them for ratios (P/E, P/B, etc.) unless no split occurred between the reporting date and today.
import xfinlink as xfl df = xfl.fundamentals( ["AAPL", "MSFT", "GOOGL"], period_type="annual", fields=["revenue", "net_income", "operating_cash_flow"], start="2024-01-01", ) print(df[["ticker", "period_end", "revenue", "net_income"]])
import xfinlink as xfl df = xfl.prices("AAPL", start="2024-01-01", end="2024-12-31") df["cumulative_return"] = (1 + df["return_daily"]).cumprod() - 1 print(f"AAPL 2024 total return: {df['cumulative_return'].iloc[-1]:.1%}")
import xfinlink as xfl info = xfl.resolve("GM") for entity in info["data"]["GM"]["entities"]: print(f"{entity['name']}: {entity['ticker_valid_from']} → {entity['ticker_valid_to']}") # General Motors Corporation (pre-2009 bankruptcy): 1962-07-02 → 2009-06-01 # General Motors Company: None → None (current)
For developers with Python + IDE
pip install xfinlinkLoading llms.txt…
Zero code — ask questions, get answers
Server URL
https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY
Replace YOUR_API_KEY with your key from the dashboard.
Available tools: get_prices, get_fundamentals, get_metrics, resolve_ticker, search, get_index, get_insiders
Option A — Web (claude.ai)
xfinlink, URL: https://api.xfinlink.com/mcp?api_key=YOUR_API_KEYAvailable on Free (1 connector), Pro, Max, Team, and Enterprise plans.
Option B — Claude Desktop
claude_desktop_config.json:{
"mcpServers": {
"xfinlink": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY"]
}
}
}Requires Plus, Pro, Team, Enterprise, or Edu plan.
xfinlink, MCP server URL: https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY, Authentication: NoneOption A — Web (grok.com)
Requires a paid Grok account.
xfinlink, URL: https://api.xfinlink.com/mcp?api_key=YOUR_API_KEYOption B — xAI API (Developer)
from openai import OpenAI client = OpenAI( api_key="your-xai-api-key", base_url="https://api.x.ai/v1", ) response = client.responses.create( model="grok-4.20-reasoning", input=[{"role": "user", "content": "What's AAPL's quarterly revenue trend?"}], tools=[{ "type": "mcp", "server_url": "https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY", "server_label": "xfinlink", }], )
Requires Pro, Max, or Enterprise plan.
xfinlink, MCP Server URL: https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY, Authentication: None, Transport: Streamable HTTPAdd to .cursor/mcp.json:
{
"mcpServers": {
"xfinlink": {
"url": "https://api.xfinlink.com/mcp?api_key=YOUR_API_KEY"
}
}
}API key limits: Free: 100/day, Pro: 10,000/day.
Sign up to get your API key. View pricing for higher limits.