Metadata-Version: 2.4
Name: xfinlink
Version: 0.13.1
Summary: Financial data API client — prices, fundamentals, entity resolution for all US equities
Author: xfinlink team
License-Expression: MIT
Project-URL: Homepage, https://xfinlink.com
Project-URL: Repository, https://github.com/xfinlink/xfinlink
Project-URL: Documentation, https://xfinlink.com/docs
Keywords: finance,stock,prices,fundamentals,SEC,EDGAR,ticker,entity-resolution,financial-data,API
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24
Requires-Dist: pandas>=1.5
Requires-Dist: typer>=0.9
Requires-Dist: rich>=13
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Dynamic: license-file

# xfinlink

Free financial data API for US equities — prices, fundamentals, metrics, entity resolution, index constituents, insider transactions, and institutional (Form 13F) holdings.

## Install

```bash
pip install -U xfinlink
```

## Quick start

```python
import xfinlink as xfl

xfl.set_api_key("your-key")  # or set XFINLINK_API_KEY env var
# Get a free key at https://xfinlink.com/signup

# Historical prices
df = xfl.prices("AAPL", start="2024-01-01", end="2024-12-31")
print(df[["date", "close", "adj_close", "volume"]].head())

# Multi-ticker
df = xfl.prices(["AAPL", "MSFT", "GOOGL"], start="2024-01-01")

# Financial statements
df = xfl.fundamentals("AAPL", period_type="annual")

# Computed metrics (P/E, ROE, margins, etc.)
df = xfl.metrics("AAPL", fields=["pe_ratio", "roe", "market_cap"])

# Entity resolution
info = xfl.resolve("GM")

# Search
df = xfl.search(q="apple")

# S&P 500 constituents
df = xfl.index("sp500")

# Institutional holdings — who held Apple at the end of 2026-Q1 (paid plans)
df = xfl.holdings("AAPL", quarter="2026-03-31")

# One manager's portfolio
mgrs = xfl.managers("berkshire")
df = xfl.manager_holdings(58, quarter="2026-03-31")

# Check usage
xfl.usage()
```

## Defaults

- `start` defaults to 1 year back if omitted — from your `end` date if you pass one, otherwise from today.
- Pagination stops at `max_rows` (default 10,000). Increase if you need more.
- `date` and `period_end` are regular DataFrame columns, not the index.

## API endpoints

| Endpoint | Use case |
|---|---|
| `GET /v1/prices/{ticker}` | Historical prices, volume, dividends, splits |
| `GET /v1/fundamentals/{ticker}` | Financial statements |
| `GET /v1/metrics/{ticker}` | Pre-computed financial metrics |
| `GET /v1/resolve/{ticker}` | Entity resolution, corporate history |
| `GET /v1/search` | Find companies by name, sector, SIC, NAICS |
| `GET /v1/index/{name}` | Index constituents (current or historical) |
| `⮑ GET /v1/index/{name}/events` | Index additions and removals as a dated event log |
| `GET /v1/insiders/{ticker}` | Insider transactions (paid plans) |
| `GET /v1/holdings/{ticker}` | Institutional Form 13F holdings — who holds a security (paid plans) |
| `GET /v1/managers` | Institutional manager lookup by name (paid plans) |
| `⮑ GET /v1/managers/{manager_id}/holdings` | One manager's reported portfolio (paid plans) |

Ticker endpoints accept comma-separated symbols, for example `/v1/prices/AAPL,MSFT,GOOGL`. Tickers per call on data endpoints scale by plan: 1 (Free), 100 (Pro), 500 (Max), 5,000 (Redistribution); `/v1/resolve` supports up to 10.

### Reaching a specific entity

A ticker always resolves to its current holder, so a company that held a ticker only in the past is not reachable by ticker. Pass an `entity_id` instead — on `/v1/prices`, `/v1/fundamentals`, `/v1/metrics`, `/v1/insiders` and `/v1/holdings`, as `?entity_id=3165` or a comma-separated list. Find ids with `/v1/resolve/{ticker}`, which lists every company that has used the ticker and when, or with `/v1/search`.

```python
# The EDS ticker serves its most recent holder
xfl.fundamentals("EDS", period="max")            # Exceed Company Ltd

# entity_id reaches the historical company the ticker cannot
xfl.fundamentals(entity_id=3165, period="max")   # Electronic Data Systems
```

`entity_id` cannot be combined with a ticker, and N ids count as N tickers against the per-plan cap. An explicit id is served as itself, with no share-class-to-issuer aliasing, so a share-class id can return no rows on fundamentals, metrics and insiders — resolve to the issuer's id first.

## Rate limits

Requests per day: Free 100 (40/hour burst), Pro 10,000, Max 50,000, Redistribution 500,000. Row volume is capped on every plan — rows/hour: Free 100K, Pro 1M, Max 5M, Redistribution 50M; rows/day: Free 500K, Pro 5M, Max 25M, Redistribution 250M. Paid plans also unlock full history (daily prices back to 1996, fundamentals back to 1950). See [pricing](https://xfinlink.com/pricing).

## Links

- Docs: https://xfinlink.com/docs
- Signup: https://xfinlink.com/signup
- LLM context: https://xfinlink.com/llms.txt
