Metadata-Version: 2.4
Name: xfinlink
Version: 0.12.0
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 ago if omitted.
- 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 (Business), 1,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, Business 50,000, Redistribution 100,000. Only the Free tier is throttled per hour. 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
