# Agent Onboarding Source: https://docs.financialdatasets.ai/agents AI agents can open their own Financial Datasets account: sign up, pay, and pull data. You are an AI agent (or you are building one). You can get a working, funded Financial Datasets API key without a dashboard, password, or OAuth. The account owner does exactly one thing: pay a Stripe link you hand them. Machine-readable version of this flow: [financialdatasets.ai/skill.md](https://www.financialdatasets.ai/skill.md) (also served at `/.well-known/skills/default/skill.md`). ## 1. Sign up ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests response = requests.post( "https://api.financialdatasets.ai/agent/signup", json={"email": "owner@realmail.com", "agent_name": "a-name-for-yourself"}, ) api_key = response.json()["api_key"] # shown once - save it now ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl -X POST "https://api.financialdatasets.ai/agent/signup" \ -H "Content-Type: application/json" \ -d '{"email": "owner@realmail.com", "agent_name": "a-name-for-yourself"}' ``` A `201` returns `api_key`. Save it immediately; it is not shown again. Rules: * `email` must be the account owner's real inbox. Placeholder domains (example.com, test.com, ...) are rejected. The confirmation email and the payment link both depend on it. * `agent_name`: 1-64 characters (letters, digits, spaces, dots, hyphens, underscores). The account owner sees it in the email, so pick something they recognize. * Lost the key? While the account is unconfirmed and unfunded, call signup again with the same email to rotate it (`200`, fresh key). After confirmation or funding, key management moves to the [dashboard](https://www.financialdatasets.ai). * `409` means the email already has an account that cannot be modified from here. At signup we email the account owner once, with a one-click confirmation link (subject: "An AI agent created a Financial Datasets account with your email"). Tell them to expect it. Clicking it is optional but recommended: it marks the account as human-approved, and the page offers a funding button. Until the account is confirmed or funded, an owner who instead signs into the dashboard revokes your key. ## 2. Pay for access Every data call returns `402 Payment Required` until the account is funded. The 402 body includes `checkout_link_endpoint` and `checkout_link_hint`. Mint the link yourself: ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests response = requests.post( "https://api.financialdatasets.ai/agent/checkout-link", headers={"X-API-KEY": api_key}, ) checkout_url = response.json()["checkout_url"] ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl -X POST "https://api.financialdatasets.ai/agent/checkout-link" \ -H "X-API-KEY: your_api_key_here" ``` The `200` response contains `checkout_url`: a Stripe Checkout page (\$20 minimum credits purchase; pass `{"amount_to_add": 50}` for more; below-minimum or non-numeric values return `400 invalid_amount_to_add`). Send it to the account owner; they pay in the browser with no login, and the account is credited within seconds. The payment page also offers optional auto-refill; if the account owner turns it on, the balance refills itself when it runs low. Paying the link can only credit the account tied to your key. Links expire after 24 hours; mint a fresh one anytime. A `502` means the link could not be created; retry. ## 3. Query data Retry your call. `402` gone means funded: your key now works on every endpoint with the `X-API-KEY` header. ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests response = requests.get( "https://api.financialdatasets.ai/financials/income-statements", params={"ticker": "AAPL", "period": "annual", "limit": 4}, headers={"X-API-KEY": api_key}, ) income_statements = response.json()["income_statements"] ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=4" \ -H "X-API-KEY: your_api_key_here" ``` When the balance runs out you will see `402` again; repeat step 2. ## Security rules for agents * Your API key is a secret. Send it only to `api.financialdatasets.ai`, only in the `X-API-KEY` header. * Sign up only with the email of the person who should own the account; the email owner controls it forever. * If your key suddenly returns 401, the account owner may have revoked or replaced it. Ask them for a new key from the dashboard; do not re-signup loop. ## What's next? Every endpoint with parameters, in agent-readable llms.txt form. Income statements, balance sheets, and cash flow statements. Historical and real-time price data. Person at the keyboard? MCP with OAuth is the faster path. # Activist Ownership Source: https://docs.financialdatasets.ai/api/activist-ownership GET /activist-ownership Track activist investor stakes from SEC Schedule 13D filings in real time. See who is building a position with intent to influence control. ### Overview The activist ownership API gives you every activist stake in US public companies, sourced from SEC Schedule 13D filings. A Schedule 13D is filed when an investor crosses 5% ownership of a company **with intent to influence control** — a proxy fight, a push for a sale, board seats, strategy changes. It is one of the fastest-moving signals in public markets, and new filings appear on this endpoint within about a minute of hitting SEC EDGAR. You can answer questions like: * Who holds activist stakes in this company right now? * What companies does a given activist currently hold? * When did an activist first cross 5%, and how has the stake changed since? To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Companies | Activist Filers | History | Updated | | --------- | --------------- | ------------------ | ----------------- | | 2,400+ | 2,900+ | Since January 2025 | Within \~1 minute | Coverage begins in January 2025, when the SEC's structured-data mandate for Schedules 13D and 13G took effect. ### Two Ways to Query Provide exactly one of `ticker` or `filer_cik`: * `ticker` — who holds activist stakes in this company * `filer_cik` — what stakes does this activist hold, across companies By default, each stake's **current state** is returned (the most recent filing in its amendment chain). Add `history=true` to get the full chain of original filings and amendments. ### Available Tickers You can fetch a list of companies with activist stakes with a `GET` request to: [https://api.financialdatasets.ai/activist-ownership/tickers/](https://api.financialdatasets.ai/activist-ownership/tickers/) ### Available Filers You can look up activist filers (and their CIKs) by owner name with a `GET` request to: [https://api.financialdatasets.ai/activist-ownership/filers/?name=saba](https://api.financialdatasets.ai/activist-ownership/filers/?name=saba) The `name` parameter matches owner names by prefix (case-insensitive). The response includes a `total` count of all matches alongside the returned page; the page size is controlled with `limit` (default `100`, max `1000`). If `total` is larger than the page you received, narrow the search with `name`. ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker` or `filer_cik` (exactly one, required), plus `history`, `limit`, and `filing_date`. **Note**: by default, `limit` is `10` (max `1000`) and `history` is `false` (current stake state only). The `filing_date` parameter is used to filter by when filings were submitted. For example, you can include filters like `filing_date_lte=2026-06-30` and `filing_date_gte=2026-01-01` to get filings from the first half of 2026. The available `filing_date` operations are: * `filing_date_lte` * `filing_date_lt` * `filing_date_gte` * `filing_date_gt` * `filing_date` Looking for passive 5% holders too? The [beneficial ownership API](/api/beneficial-ownership) returns both activist (13D) and passive (13G) stakes, with a `type` filter. ### Example (by ticker) ```python Activist Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'BB' # stock ticker limit = 50 # number of rows to return # create the URL url = ( f'https://api.financialdatasets.ai/activist-ownership' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse activist_owners from the response activist_owners = response.json().get('activist_owners') ``` ### Example (by filer) ```python Activist Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params filer_cik = '1510281' # Saba Capital's SEC CIK limit = 50 # number of rows to return # create the URL url = ( f'https://api.financialdatasets.ai/activist-ownership' f'?filer_cik={filer_cik}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse activist_owners from the response activist_owners = response.json().get('activist_owners') ``` ### Example (full stake history) ```python Activist Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'BB' # stock ticker history = 'true' # include the full amendment chain # create the URL url = ( f'https://api.financialdatasets.ai/activist-ownership' f'?ticker={ticker}' f'&history={history}' ) # make API request response = requests.get(url, headers=headers) # parse activist_owners from the response activist_owners = response.json().get('activist_owners') ``` # Beneficial Ownership Source: https://docs.financialdatasets.ai/api/beneficial-ownership GET /beneficial-ownership See every holder of more than 5% of a US public company, from SEC Schedules 13D and 13G. Activist and passive stakes with full amendment history. ### Overview The beneficial ownership API returns the holders of more than 5% of a class of a company's shares, sourced from SEC Schedules 13D and 13G. Both schedules report the same thing — a 5%+ stake — and differ by intent: * **Schedule 13D** (`type=activist`): the holder may seek to influence control (proxy fights, board seats, pushing for a sale). * **Schedule 13G** (`type=passive`): the holder certifies passive intent (typically large asset managers). A stake can move between the two over time: an activist settles and goes passive, or a passive holder turns active. This endpoint keeps each stake's full story in one place, so you never lose a position across that transition. You can answer questions like: * Who owns more than 5% of this company, and how much exactly? * Which of those holders are activists versus passive institutions? * How has a specific holder's position changed filing by filing? To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Companies | Filers | History | Updated | | --------- | ------ | ------------------ | ------------------------------------------------------- | | 6,400+ | 8,100+ | Since January 2025 | Activist stakes within \~1 minute; passive stakes daily | Coverage begins in January 2025, when the SEC's structured-data mandate for Schedules 13D and 13G took effect. ### Two Ways to Query Provide exactly one of `ticker` or `filer_cik`: * `ticker` — who owns more than 5% of this company * `filer_cik` — what stakes does this filer hold, across companies By default, each stake's **current state** is returned (the most recent filing in its amendment chain). Add `history=true` to get the full chain of original filings and amendments. ### Available Tickers You can fetch a list of companies with 5%+ holders with a `GET` request to: [https://api.financialdatasets.ai/beneficial-ownership/tickers/](https://api.financialdatasets.ai/beneficial-ownership/tickers/) ### Available Filers You can look up filers (and their CIKs) by owner name with a `GET` request to: [https://api.financialdatasets.ai/beneficial-ownership/filers/?name=vanguard](https://api.financialdatasets.ai/beneficial-ownership/filers/?name=vanguard) The `name` parameter matches owner names by prefix (case-insensitive). The response includes a `total` count of all matches alongside the returned page; the page size is controlled with `limit` (default `100`, max `1000`). If `total` is larger than the page you received, narrow the search with `name`. ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker` or `filer_cik` (exactly one, required), plus `type`, `history`, `limit`, and `filing_date`. **Note**: by default, `limit` is `10` (max `1000`), `type` is `null` (both activist and passive), and `history` is `false` (current stake state only). The `type` parameter filters to `activist` (Schedule 13D) or `passive` (Schedule 13G) stakes. The `filing_date` parameter is used to filter by when filings were submitted. For example, you can include filters like `filing_date_lte=2026-06-30` and `filing_date_gte=2026-01-01` to get filings from the first half of 2026. The available `filing_date` operations are: * `filing_date_lte` * `filing_date_lt` * `filing_date_gte` * `filing_date_gt` * `filing_date` Only interested in activists? The [activist ownership API](/api/activist-ownership) is a dedicated view of the same data, pinned to activist stakes and updated in real time. ### Example (by ticker) ```python Beneficial Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker limit = 50 # number of rows to return # create the URL url = ( f'https://api.financialdatasets.ai/beneficial-ownership' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse beneficial_owners from the response beneficial_owners = response.json().get('beneficial_owners') ``` ### Example (passive stakes only) ```python Beneficial Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker type = 'passive' # 13G stakes only # create the URL url = ( f'https://api.financialdatasets.ai/beneficial-ownership' f'?ticker={ticker}' f'&type={type}' ) # make API request response = requests.get(url, headers=headers) # parse beneficial_owners from the response beneficial_owners = response.json().get('beneficial_owners') ``` ### Example (by filer, with history) ```python Beneficial Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params filer_cik = '915191' # the filer's SEC CIK history = 'true' # include the full amendment chain # create the URL url = ( f'https://api.financialdatasets.ai/beneficial-ownership' f'?filer_cik={filer_cik}' f'&history={history}' ) # make API request response = requests.get(url, headers=headers) # parse beneficial_owners from the response beneficial_owners = response.json().get('beneficial_owners') ``` # Facts (by CIK) Source: https://docs.financialdatasets.ai/api/company/facts/cik GET /company/facts Get company information and facts by SEC CIK number. Includes sector, industry, market cap, and corporate details. ### Overview Company facts includes data like name, CIK, total employees, website URL, and more. The company facts API provides a simple way to access the most important high-level information about a company. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 28,000+ | Current | Real-time | ### Available CIKs You can fetch a list of available CIKs with a `GET` request to: [https://api.financialdatasets.ai/company/facts/ciks/](https://api.financialdatasets.ai/company/facts/ciks/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `cik` filter the data. 3. Execute the API request. **Note**: You must include the `cik` in your query params. ### Example ```python Company Facts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params cik = '0000320193' # create the URL url = ( f'https://api.financialdatasets.ai/company/facts' f'?cik={cik}' ) # make API request response = requests.get(url, headers=headers) # parse company_facts from the response company_facts = response.json().get('company_facts') ``` # Facts (by ticker) Source: https://docs.financialdatasets.ai/api/company/facts/ticker GET /company/facts Get company information and facts by stock ticker. Includes sector, industry, market cap, employee count, and more. ### Overview Company facts includes data like name, CIK, total employees, website URL, and more. The company facts API provides a simple way to access the most important high-level information about a company. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 28,000+ | Current | Real-time | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/company/facts/tickers/](https://api.financialdatasets.ai/company/facts/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` filter the data. 3. Execute the API request. **Note**: You must include the `ticker` in your query params. ### Example ```python Company Facts theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # create the URL url = ( f'https://api.financialdatasets.ai/company/facts' f'?ticker={ticker}' ) # make API request response = requests.get(url, headers=headers) # parse company_facts from the response company_facts = response.json().get('company_facts') ``` # Company Earnings Source: https://docs.financialdatasets.ai/api/earnings GET /earnings Get quarterly and annual earnings data for a single company. Includes EPS actuals, estimates, surprise, and report dates. ### Overview The Earnings API returns the most recent SEC filings tied to a company's earnings periods. The response is a flat list — each entry IS one filing (e.g. the initial 8-K earnings release, or a later 10-Q / 10-K / 20-F) — sorted by `(report_period DESC, filing_date ASC)`. Each entry includes: * Key income statement fields (e.g. revenue, net income, EPS) * Key balance sheet fields (e.g. cash, debt, assets, liabilities) * Key cash flow fields (e.g. operating cash flow, capex, free cash flow) Each entry can include both `quarterly` and `annual` data. **Important**: This endpoint returns figures from a company's initial earnings release, typically filed as an 8-K with the SEC. Because an 8-K is a preliminary snapshot, some fields may be `null` — this simply means the company did not report that figure in its initial release. Full financial statements (income statements, balance sheets, and cash flow statements) are published later via 10-K and 10-Q filings and can be retrieved through our [/financials endpoint](/api/financials/income-statements). **Real-time availability**: For non-Enterprise customers, real-time earnings are currently available only for companies in the S\&P 500. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ---------------- | | 6,000+ | 2+ years | Within 5 seconds | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/earnings/tickers/](https://api.financialdatasets.ai/earnings/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the required query param `ticker`. 3. Execute the API request. ### Example ```python Earnings theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ticker = "AAPL" url = f"https://api.financialdatasets.ai/earnings?ticker={ticker}" response = requests.get(url, headers=headers) data = response.json() earnings = data["earnings"] ``` ### Notes * The top-level `earnings` is a flat list of filings sorted by `(report_period DESC, filing_date ASC)`. With `limit=N`, up to `N` report-periods worth of filings are returned — the entry count may exceed `N` when a recent period has both an 8-K and a 10-Q/10-K. * `report_period` repeats across consecutive entries when one period has multiple filings (e.g. the initial 8-K earnings release followed by the later 10-Q). The 8-K appears first because it has the earlier `filing_date`. * `filing_date` and `filing_datetime` are both expressed in **Eastern Time** (the SEC's operating timezone). `filing_datetime` is the precise sub-day moment SEC accepted the filing; `filing_date` is its calendar day. * An 8-K is preliminary, so its `quarterly` / `annual` blocks may omit fields the company didn't disclose at release time. The matching 10-Q / 10-K typically fills those in. For complete financials, use the [/financials endpoint](/api/financials/income-statements). * `quarterly` and `annual` may be omitted from an entry when data isn't available for that time dimension. * `*_chg` fields (e.g. `revenue_chg`, `net_income_chg`) are returned only when calculable. * Sources are limited to SEC filings: `8-K`, `10-Q`, `10-K`, and `20-F`. # Earnings Feed Source: https://docs.financialdatasets.ai/api/earnings/feed GET /earnings A real-time feed of the most recently filed earnings across all covered companies. ### Overview The Earnings Feed returns the most recent earnings filings across all covered companies, sorted by SEC filing date (newest first). Use it to power dashboards, alerts, or any view of "what just got reported." Each entry follows the same `EarningsRecord` shape as the company-earnings response — see [Earnings](/api/earnings) for the full field reference. The feed sorts by `filing_date` descending (most recently filed first) and dedupes by `(ticker, report_period)`. As a company progresses from its initial 8-K earnings release to the full 10-Q or 10-K filing, the entry updates to reflect the most complete data available. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ---------------- | | 6,000+ | 2+ years | Within 5 seconds | ### Getting Started Call `GET /earnings/` **without** the `ticker` query param: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Optionally provide `limit` (default `10`, max `100`). 3. Execute the API request. ### Example ```python Earnings Feed theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } # Top 10 most recently filed earnings across all companies url = "https://api.financialdatasets.ai/earnings/" response = requests.get(url, headers=headers) data = response.json() feed = data["earnings"] ``` ### Notes * **Sort order**: items are returned newest-first by SEC `filing_date`. * **Dedup**: each `(ticker, report_period)` appears once per response. When both an 8-K earnings release and the corresponding 10-Q/10-K are available, the more complete filing is shown. * **`source_type`**: identifies the underlying SEC form — `8-K` (preliminary earnings release), `10-Q` (quarterly), `10-K` (annual), or `20-F` (foreign annual). * **Polling**: results are cached briefly server-side; expect near-real-time freshness as new filings land. # Items Source: https://docs.financialdatasets.ai/api/filings/items GET /filings/items Get specific sections and items from SEC filings, like Item 1A Risk Factors or Item 7 MD&A. ### Overview The Items endpoint allows you to retrieve the raw text from the sections (called items) from a given 10-K, 10-Q, or 8-K filing. This lets you easily extract data from a filing without having to parse the entire document on your own. For 8-K filings, items may include an `exhibits` array when exhibits are present. Use the `include_exhibits` parameter to retrieve the raw text content of linked exhibits. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 22,000+ | 30+ years | Real-time | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/filings/tickers/](https://api.financialdatasets.ai/filings/tickers/) ### Valid Item Types You can fetch a list of valid item types for 10-K, 10-Q, and 8-K filings with a `GET` request to: [https://api.financialdatasets.ai/filings/items/types/](https://api.financialdatasets.ai/filings/items/types/) You can optionally filter by filing type using the `filing_type` query parameter: * `https://api.financialdatasets.ai/filings/items/types/?filing_type=10-K` - returns only 10-K item types * `https://api.financialdatasets.ai/filings/items/types/?filing_type=10-Q` - returns only 10-Q item types * `https://api.financialdatasets.ai/filings/items/types/?filing_type=8-K` - returns only 8-K item types The response includes the item name, title, and description for each valid item type. 8-K item names follow the SEC's numbering scheme in the format `Item-X.XX`, for example `Item-1.01`, `Item-2.02`, `Item-5.02`, `Item-8.01`, and `Item-9.01`. ### Filtering by item Use the `item` query parameter (repeatable) to return only the items you need. This works for all three filing types. Because a given 8-K contains only the items the company chose to report, requesting an item that is not in the filing returns a `404` that names the missing items and the items the filing does contain (see [Error handling](#error-handling)). ### Examples ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' filing_type = '10-K' year = 2023 # create the URL url = ( f'https://api.financialdatasets.ai/filings/items' f'?ticker={ticker}' f'&filing_type={filing_type}' f'&year={year}' ) # make API request response = requests.get(url, headers=headers) # parse filings from the response items = response.json().get('items') ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' filing_type = '10-Q' year = 2023 quarter = 1 # create the URL url = ( f'https://api.financialdatasets.ai/filings/items' f'?ticker={ticker}' f'&filing_type={filing_type}' f'&year={year}' f'&quarter={quarter}' ) # make API request response = requests.get(url, headers=headers) # parse filings from the response items = response.json().get('items') ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params (all required) ticker = 'AAPL' filing_type = '8-K' accession_number = '0001277902-25-000182' include_exhibits = True # create the URL url = ( f'https://api.financialdatasets.ai/filings/items' f'?ticker={ticker}' f'&filing_type={filing_type}' f'&accession_number={accession_number}' f'&include_exhibits={include_exhibits}' ) # make API request response = requests.get(url, headers=headers) # parse filings from the response items = response.json().get('items') ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' filing_type = '10-K' year = 2023 # create the URL url = ( f'https://api.financialdatasets.ai/filings/items' f'?ticker={ticker}' f'&filing_type={filing_type}' f'&year={year}' f'&item=Item-1' # Item 1 f'&item=Item-7A' # Item 7A ) # 8-K filings can be filtered the same way, e.g.: # &item=Item-2.02&item=Item-9.01 # make API request response = requests.get(url, headers=headers) # parse items from the response items = response.json().get('items') ``` ### Asynchronous requests (202 Accepted) Most requests return data immediately. The first request for a filing we haven't processed yet can take longer. If your filing isn't ready within \~10 seconds, the API returns `202 Accepted` with a `result_url` to poll. Your request is never dropped. ```http theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} HTTP/1.1 202 Accepted Location: https://api.financialdatasets.ai/filings/items/requests/1c2f0a4e-... Retry-After: 30 Content-Type: application/json { "status": "processing", "request_id": "1c2f0a4e-...", "result_url": "https://api.financialdatasets.ai/filings/items/requests/1c2f0a4e-...", "estimated_ready_at": "2026-07-13T18:30:45Z", "accession_number": "0001277902-25-000182", "message": "We are processing this filing. Poll result_url for the result, or retry this request after the estimated ready time." } ``` Poll `result_url` with the same `X-API-KEY` header. Each poll returns one of three responses: | Response | Meaning | What to do | | ------------------------------- | -------------------------------- | ------------------------------------------------------------- | | `{"status": "processing", ...}` | Still preparing the filing | Wait `Retry-After` seconds, then poll again | | The filing items payload | Ready | Done. You are billed once, on this response | | `{"status": "failed", ...}` | The filing could not be prepared | Re-request `GET /filings/items` with your original parameters | ```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} sequenceDiagram participant You participant Financial Datasets You->>Financial Datasets: GET /filings/items?ticker=AAPL&... Financial Datasets-->>You: 202 Accepted (result_url) You->>Financial Datasets: GET result_url Financial Datasets-->>You: 200 {"status": "processing"} Note over You: wait Retry-After seconds You->>Financial Datasets: GET result_url Financial Datasets-->>You: 200 filing items (billed once) ``` **Example with polling (Python):** ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import time import requests def get_filing_items(url, headers): response = requests.get(url, headers=headers) if response.status_code == 202: result_url = response.json()["result_url"] while True: time.sleep(int(response.headers.get("Retry-After", 30))) response = requests.get(result_url, headers=headers) body = response.json() if body.get("status") == "processing": continue if body.get("status") == "failed": raise RuntimeError(body["message"]) break # body is the filing items payload return response.json() ``` **Good to know:** * Most filings are ready within 30 seconds. If a filing can't be prepared within 5 minutes, polling returns `failed`. * You are only billed when data is delivered. A 202, a processing poll, or a failed request never costs anything. * Retrying your original request URL also works: once the filing is ready, the same request returns it immediately. The `result_url` is simply the version that can also tell you definitively that a filing failed. ### Error handling Requests with mismatched parameters fail immediately with a `400` instead of being accepted for processing. The error message always names the correct value so you can fix the request in one step. | Status | Error | Meaning | What to do | | ---------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | | `400` | `Filing type mismatch` | The accession number belongs to a different form type than `filing_type` | Retry with the `filing_type` named in the message | | `400` | `Filing company mismatch` | The accession number belongs to a different company than `ticker` | Retry with the `ticker` named in the message | | `404` | `Filing not found` | The accession number does not exist on SEC EDGAR for this ticker | Verify the accession number and ticker | | `404` | `Items not found in filing` | At least one requested `item` is not in this filing (common for 8-Ks, which contain only the items the company reported) | The message lists the items the filing does contain. Retry with those, or drop the `item` filter to get all items. You are not billed | | `404` | `No data found` | The filing exists but contains no extractable items | Nothing to retry. You are not billed | | `200` `{"status": "failed"}` | Returned by `result_url` | The filing could not be prepared | Re-request `GET /filings/items` with your original parameters | ```json 400 Filing type mismatch theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "error": "Filing type mismatch", "message": "Accession number 0001277902-25-000182 is a 10-K, not a 8-K. Retry with filing_type=10-K.", "accession_number": "0001277902-25-000182" } ``` ```json 404 Items not found in filing theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "error": "Items not found in filing", "message": "The following requested item(s) do not exist in this filing: Item 2.02. Items present in this filing: Item 5.02, Item 9.01.", "accession_number": "0001277902-25-000182" } ``` # Filings Source: https://docs.financialdatasets.ai/api/filings/ticker GET /filings Search SEC filings (10-K, 10-Q, 8-K) for any US public company by stock ticker. ### Overview The Filings endpoint allows you to fetch a list of filings for a given company. The endpoint returns all of the filings that the company has filed with the SEC. This includes 10-Ks, 10-Qs, 8-Ks, and more. We have SEC filings for 10,000+ public companies. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 22,000+ | 30+ years | Real-time | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/filings/tickers/](https://api.financialdatasets.ai/filings/tickers/) ### Available Filing Types You can fetch a list of valid filing types with a `GET` request to: [https://api.financialdatasets.ai/filings/types/](https://api.financialdatasets.ai/filings/types/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` to filter the data. 3. Execute the API request. **Note**: You must include either the `ticker` in your query params. ### Example ```python Filings theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' limit = 10 # create the URL url = ( f'https://api.financialdatasets.ai/filings' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse filings from the response filings = response.json().get('filings') ``` ### Filtering by Filing Type Use the `filing_type` query param to filter filings. * Single type: `?ticker=AAPL&filing_type=10-K` * Multiple types: repeat the param (same pattern as multi-`item` filtering), e.g. `?ticker=AAPL&filing_type=10-Q&filing_type=10-K` ```python FilingsWithMultipleTypes theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = {"X-API-KEY": "your_api_key_here"} url = "https://api.financialdatasets.ai/filings" params = [ ("ticker", "AAPL"), ("filing_type", "10-Q"), ("filing_type", "10-K"), ] response = requests.get(url, headers=headers, params=params) filings = response.json().get("filings") ``` # Historical Source: https://docs.financialdatasets.ai/api/financial-metrics/historical GET /financial-metrics Get historical financial metrics and ratios for any US stock ticker. Includes P/E, EV/EBITDA, ROE, and 100+ metrics. ### Overview The financial metrics API provides metrics and ratios for a given stock ticker based on the latest and historical fundamentals data from financial statements. Financial metrics include a company's valuation, profitability, efficiency, liquidity, leverage, growth, and per share metrics over the requested period. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financial-metrics/tickers/](https://api.financialdatasets.ai/financial-metrics/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. By default, `limit` is `4` and `report_period` is `null`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the financial metrics. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get financial metrics between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Example ```python Financial Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual', 'quarterly', or 'ttm' limit = 30 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financial-metrics' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse financial_metrics from the response financial_metrics = response.json().get('financial_metrics') ``` ### Example (with report\_period) ```python Financial Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' period = 'ttm' report_period_lte = '2024-01-01' # end date report_period_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/financial-metrics' f'?ticker={ticker}' f'&period={period}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse financial_metrics from the response financial_metrics = response.json().get('financial_metrics') ``` # Snapshot Source: https://docs.financialdatasets.ai/api/financial-metrics/snapshot GET /financial-metrics/snapshot Get a real-time snapshot of current financial metrics and valuation ratios for any US stock ticker. ### Overview We have real-time financial metrics for all actively-traded equities in the US. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 13,000+ | Latest | Within 1 second | ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` to filter the data. 3. Execute the API request. **Note**: You must provide the `ticker`. ### Example ```python Financial Metrics Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # create the URL url = ( f'https://api.financialdatasets.ai/financial-metrics/snapshot' f'?ticker={ticker}' ) # make API request response = requests.get(url, headers=headers) # parse snapshot from the response snapshot = response.json().get('snapshot') ``` # All Financial Statements Source: https://docs.financialdatasets.ai/api/financials/all-financial-statements GET /financials Get all financial statements (income, balance sheet, cash flow) for any US stock in a single API call. ### Overview This endpoint aggregates all financial statements for a ticker into a single API call. So, instead of calling 3 endpoints to get income statements, balance sheets, and cash flow statements, you can call this endpoint once and get all financial statements in one go. The endpoint returns the following financial statements: * [Income Statements](/api/financials/income-statements) * [Balance Sheets](/api/financials/balance-sheets) * [Cash Flow Statements](/api/financials/cash-flow-statements) To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/tickers/](https://api.financialdatasets.ai/financials/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`,`limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Normalized vs. As-Reported We support two views of each financial statement: * **Normalized** (this endpoint, `GET /financials`): every filer mapped onto a single canonical schema. Consistent across companies and ideal for cross-company comparison and time-series analysis. Available from the 1990s onward. * **As-Reported** (`GET /financials/as-reported`): each statement exactly as filed in the 10-K or 10-Q, with original labels and parent-child line item hierarchy. Ideal when you need the exact wording, ordering, or subtotal structure from the filing. Available from 2010 onward, when XBRL became standard for SEC filings and companies started to report more granular data. ### Examples ```python Normalized theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual', 'quarterly', or 'ttm' limit = 30 # number of statements to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse financials from the response financials = response.json().get('financials') # get income statements income_statements = financials.get('income_statements') # get balance sheets balance_sheets = financials.get('balance_sheets') # get cash flow statements cash_flow_statements = financials.get('cash_flow_statements') ``` ```python As-Reported theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/as-reported' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse as_reported_financials from the response as_reported_financials = response.json().get('as_reported_financials') ``` # All Segmented Financials Source: https://docs.financialdatasets.ai/api/financials/all-segments GET /financials/segments Get all segment breakdowns (income statement, balance sheet, cash flow) for any US stock in a single API call. ### Overview This endpoint aggregates segment breakdowns from all three financial statement types into a single API call. So, instead of calling 3 endpoints to get income statement segments, balance sheet segments, and cash flow statement segments, you can call this endpoint once and get all segment data in one go. The endpoint returns segment breakdowns for: * [Income Statement Segments](/api/financials/income-statement-segments) — revenue, operating income, depreciation * [Balance Sheet Segments](/api/financials/balance-sheet-segments) — assets, goodwill, long-lived assets * [Cash Flow Statement Segments](/api/financials/cash-flow-statement-segments) — capital expenditure To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 6,400+ | 15+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/segments/tickers/](https://api.financialdatasets.ai/financials/segments/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`, `limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual` or `quarterly`. The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Example ```python All Segmented Financials theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') # each element is a per-period snapshot with all three statement types for period_data in segmented_financials: income_statement = period_data.get('income_statement') # dict or None balance_sheet = period_data.get('balance_sheet') # dict or None cash_flow_statement = period_data.get('cash_flow_statement') # dict or None ``` ### Example (with report\_period) ```python All Segmented Financials theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' period = 'annual' limit = 100 report_period_lte = '2024-01-01' # end date report_period_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/financials/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` # Balance Sheet Source: https://docs.financialdatasets.ai/api/financials/balance-sheet-segments GET /financials/balance-sheets/segments Get balance sheet segment breakdowns (assets, goodwill, long-lived assets) by business segment for any US public company. ### Overview The balance sheet segments API provides as-reported segment breakdowns from SEC filings (10-Ks and 10-Qs) for a given stock ticker. This includes segment data for metrics like: * **Assets** — by business segment * **Goodwill** — by business segment * **Long-Lived Assets** — by business segment These breakdowns are essential for sum-of-the-parts valuation, where analysts value each business segment independently. The API returns this data in a clean, structured format: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "segmented_financials": [ { "ticker": "AAPL", "report_period": "2025-12-27", "period": "quarterly", "assets": { "segment": [ {"label": "Americas", "value": 50000000000.0}, {"label": "Europe", "value": 35000000000.0}, {"label": "Greater China", "value": 20000000000.0} ] }, "goodwill": { "segment": [ {"label": "Americas", "value": 5000000000.0}, {"label": "Europe", "value": 3000000000.0} ] } } ] } ``` To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 6,200+ | 15+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/balance-sheets/segments/tickers/](https://api.financialdatasets.ai/financials/balance-sheets/segments/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`, `limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual` or `quarterly`. The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Example ```python Balance Sheet Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/balance-sheets/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` ### Example (with report\_period) ```python Balance Sheet Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' period = 'annual' limit = 100 report_period_lte = '2024-01-01' # end date report_period_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/financials/balance-sheets/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` # Balance Sheets Source: https://docs.financialdatasets.ai/api/financials/balance-sheets GET /financials/balance-sheets Get balance sheet data for any US stock ticker. Assets, liabilities, and equity with 30+ years of history. ### Overview The balance sheets API provides balance sheet data for a given stock ticker. Balance sheets are financial statements that summarize a company's assets, liabilities, and shareholders' equity at a specific point in time. You can filter the data by `ticker`, `period`, `limit`, and `cik`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of statements to return. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/balance-sheets/tickers/](https://api.financialdatasets.ai/financials/balance-sheets/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`,`limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Normalized vs. As-Reported We support two views of the balance sheet: * **Normalized** (this endpoint, `GET /financials/balance-sheets`): every filer mapped onto a single canonical schema (`total_assets`, `total_liabilities`, `shareholders_equity`, etc.). Consistent across companies and ideal for cross-company comparison and time-series analysis. Available from the 1990s onward. * **As-Reported** (`GET /financials/balance-sheets/as-reported`): the balance sheet exactly as filed in the 10-K or 10-Q, with original labels and parent-child line item hierarchy. Ideal when you need the exact wording, ordering, or subtotal structure from the filing. Available from 2010 onward, when XBRL became standard for SEC filings and companies started to report more granular data. ### Examples ```python Normalized theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual', 'quarterly', or 'ttm' limit = 30 # number of statements to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/balance-sheets' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse balance_sheets from the response balance_sheets = response.json().get('balance_sheets') ``` ```python As-Reported theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/balance-sheets/as-reported' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse as_reported_balance_sheets from the response as_reported_balance_sheets = response.json().get('as_reported_balance_sheets') ``` # Cash Flow Statement Source: https://docs.financialdatasets.ai/api/financials/cash-flow-statement-segments GET /financials/cash-flow-statements/segments Get cash flow statement segment breakdowns (capital expenditure) by business segment for any US public company. ### Overview The cash flow statement segments API provides as-reported segment breakdowns from SEC filings (10-Ks and 10-Qs) for a given stock ticker. This includes segment data for metrics like: * **Capital Expenditure** — by business segment Capital expenditure breakdowns by segment help analysts understand where a company is investing for growth. The API returns this data in a clean, structured format: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "segmented_financials": [ { "ticker": "AAPL", "report_period": "2025-12-27", "period": "quarterly", "capital_expenditure": { "segment": [ {"label": "Americas", "value": 3000000000.0}, {"label": "Europe", "value": 2000000000.0}, {"label": "Greater China", "value": 1500000000.0} ] } } ] } ``` To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 5,900+ | 15+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/cash-flow-statements/segments/tickers/](https://api.financialdatasets.ai/financials/cash-flow-statements/segments/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`, `limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual` or `quarterly`. The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Example ```python Cash Flow Statement Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/cash-flow-statements/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` ### Example (with report\_period) ```python Cash Flow Statement Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' period = 'annual' limit = 100 report_period_lte = '2024-01-01' # end date report_period_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/financials/cash-flow-statements/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` # Cash Flow Statements Source: https://docs.financialdatasets.ai/api/financials/cash-flow-statements GET /financials/cash-flow-statements Get cash flow statements for any US stock ticker. Operating, investing, and financing cash flows over 30+ years. ### Overview The cash flow statemenet API provides a company's cash inflows and outflows over a specific period. Cash flow statements are divided into three sections: operating activities, investing activities, and financing activities. You can filter the data by `ticker`, `period`, `limit`, and `cik`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of statements to return. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/cash-flow-statements/tickers/](https://api.financialdatasets.ai/financials/cash-flow-statements/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`,`limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Normalized vs. As-Reported We support two views of the cash flow statement: * **Normalized** (this endpoint, `GET /financials/cash-flow-statements`): every filer mapped onto a single canonical schema (`net_cash_flow_from_operations`, `capital_expenditure`, etc.). Consistent across companies and ideal for cross-company comparison and time-series analysis. Available from the 1990s onward. * **As-Reported** (`GET /financials/cash-flow-statements/as-reported`): the cash flow statement exactly as filed in the 10-K or 10-Q, with original labels and parent-child line item hierarchy. Ideal when you need the exact wording, ordering, or subtotal structure from the filing. Available from 2010 onward, when XBRL became standard for SEC filings and companies started to report more granular data. ### Examples ```python Normalized theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual', 'quarterly', or 'ttm' limit = 30 # number of statements to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/cash-flow-statements' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse cash_flow_statements from the response cash_flow_statements = response.json().get('cash_flow_statements') ``` ```python As-Reported theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/cash-flow-statements/as-reported' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse as_reported_cash_flow_statements from the response as_reported_cash_flow_statements = response.json().get('as_reported_cash_flow_statements') ``` # Income Statement Source: https://docs.financialdatasets.ai/api/financials/income-statement-segments GET /financials/income-statements/segments Get income statement segment breakdowns (revenue, operating income, depreciation) by product and business segment for any US public company. ### Overview The income statement segments API provides as-reported segment breakdowns from SEC filings (10-Ks and 10-Qs) for a given stock ticker. This includes segment data for metrics like: * **Revenue** — by product line and business segment * **Operating Income** — by business segment * **Depreciation** — by business segment For [example](https://api.financialdatasets.ai/financials/income-statements/segments/?ticker=AAPL\&limit=1\&period=annual), Apple Inc. reports revenue broken down by product (iPhone, Mac, iPad, Services, Wearables) and by geography (Americas, Europe, Greater China, Japan, Rest of Asia Pacific). The API returns this data in a clean, structured format: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "segmented_financials": [ { "ticker": "AAPL", "report_period": "2025-12-27", "period": "quarterly", "revenue": { "product": [ {"label": "iPhone", "value": 85269000000.0}, {"label": "Services", "value": 30013000000.0}, {"label": "Wearables, Home and Accessories", "value": 11493000000.0}, {"label": "iPad", "value": 8595000000.0}, {"label": "Mac", "value": 8386000000.0} ], "segment": [ {"label": "Americas", "value": 58529000000.0}, {"label": "Europe", "value": 38146000000.0}, {"label": "Greater China", "value": 25526000000.0}, {"label": "Rest of Asia Pacific", "value": 12142000000.0}, {"label": "Japan", "value": 9413000000.0} ] }, "operating_income": { "segment": [ {"label": "Americas", "value": 23953000000.0}, {"label": "Europe", "value": 17790000000.0}, {"label": "Greater China", "value": 11792000000.0}, {"label": "Rest of Asia Pacific", "value": 5686000000.0}, {"label": "Japan", "value": 4613000000.0} ] } } ] } ``` To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 6,400+ | 15+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/income-statements/segments/tickers/](https://api.financialdatasets.ai/financials/income-statements/segments/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`, `limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual` or `quarterly`. The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Example ```python Income Statement Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/income-statements/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` ### Example (with report\_period) ```python Income Statement Segments theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' period = 'annual' limit = 100 report_period_lte = '2024-01-01' # end date report_period_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/financials/income-statements/segments' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse segmented_financials from the response segmented_financials = response.json().get('segmented_financials') ``` # Income Statements Source: https://docs.financialdatasets.ai/api/financials/income-statements GET /financials/income-statements Get income statements for any US stock ticker. Revenue, expenses, and net income over 30+ years of history. ### Overview The income statements API provides income statements for a given stock ticker. Income statements are financial statements that provide information about a company's revenues, expenses, and profits over a specific period. You can filter the data by `ticker`, `period`, `limit`, and `cik`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of statements to return. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/financials/income-statements/tickers/](https://api.financialdatasets.ai/financials/income-statements/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker`, `period` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `period`, `limit`, and `report_period`. **Note**: `ticker` and `period` are required. Alternatively, you can use `cik` instead of `ticker` as a company identifier in your request. By default, `period` is `annual`,`limit` is `4`, and `report_period` is `null`. The `period` parameter can be set to `annual`, `quarterly`, or `ttm` (trailing twelve months). The `limit` parameter is used to specify the number of periods to return. The `report_period` parameter is used to specify the date of the statement. For example, you can include filters like `report_period_lte=2024-09-30` and `report_period_gte=2024-01-01` to get statements between January 1, 2024 and September 30, 2024. The available `report_period` operations are: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` ### Normalized vs. As-Reported We support two views of the income statement: * **Normalized** (this endpoint, `GET /financials/income-statements`): every filer mapped onto a single canonical schema (`revenue`, `operating_income`, etc.). Consistent across companies and ideal for cross-company comparison and time-series analysis. Available from the 1990s onward. * **As-Reported** (`GET /financials/income-statements/as-reported`): the income statement exactly as filed in the 10-K or 10-Q, with original labels and parent-child line item hierarchy. Ideal when you need the exact wording, ordering, or subtotal structure from the filing. Available from 2010 onward, when XBRL became standard for SEC filings and companies started to report more granular data. ### Examples ```python Normalized theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual', 'quarterly', or 'ttm' limit = 30 # number of statements to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/income-statements' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse income_statements from the response income_statements = response.json().get('income_statements') ``` ```python As-Reported theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker period = 'annual' # possible values are 'annual' or 'quarterly' limit = 5 # number of periods to return # create the URL url = ( f'https://api.financialdatasets.ai/financials/income-statements/as-reported' f'?ticker={ticker}' f'&period={period}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse as_reported_income_statements from the response as_reported_income_statements = response.json().get('as_reported_income_statements') ``` # Line Items Source: https://docs.financialdatasets.ai/api/financials/search-line-items POST /financials/search/line-items Search for specific financial statement line items across all US public companies. ### Overview This Line Items Search API lets you pull specific line items for a list of tickers by specifying a set of `line_items` in your request. Line items are financial data points that are found in the income statement, balance sheet, and cash flow statement. Examples of line items are revenue, net income, total debt, free cash flow, and so on. The purpose of this API is to let you easily get specific data points for a list of tickers in a single API request. You can also specify a `start_date` and `end_date` to filter the line items by a specific date range. Finally, you can specify a `period`, which must be one of `"ttm"`, `"annual"`, or `"quarterly"`. For example, you can search for `net_income` and `total_debt` for NVDA and AAPL and receive the following response: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "search_results": [ { "ticker": "NVDA", "report_period": "2024-07-28", "period": "ttm", "net_income": 53008000000, "total_debt": 9765000000 }, { "ticker": "AAPL", "report_period": "2024-06-29", "period": "ttm", "net_income": 101956000000, "total_debt": 101304000000 } ] } ``` ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 19,000+ | 30+ years | Within 1 second | ### Available Line Items ```python Income Statement theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid line_items for the income statement line_items = [ "consolidated_income", "cost_of_revenue", "dividends_per_common_share", "earnings_per_share", "earnings_per_share_diluted", "ebit", "ebit_usd", "earnings_per_share_usd", "gross_profit", "income_tax_expense", "interest_expense", "net_income", "net_income_common_stock", "net_income_common_stock_usd", "net_income_discontinued_operations", "net_income_non_controlling_interests", "operating_expense", "operating_income", "preferred_dividends_impact", "research_and_development", "revenue", "revenue_usd", "selling_general_and_administrative_expenses", "weighted_average_shares", "weighted_average_shares_diluted", ] ``` ```python Balance Sheet theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid line_items for the balance sheet line_items = [ "accumulated_other_comprehensive_income", "cash_and_equivalents", "cash_and_equivalents_usd", "current_assets", "current_debt", "current_investments", "current_liabilities", "deferred_revenue", "deposit_liabilities", "goodwill_and_intangible_assets", "inventory", "investments", "non_current_assets", "non_current_debt", "non_current_investments", "non_current_liabilities", "outstanding_shares", "property_plant_and_equipment", "retained_earnings", "shareholders_equity", "shareholders_equity_usd", "tax_assets", "tax_liabilities", "total_assets", "total_debt", "total_debt_usd", "total_liabilities", "trade_and_non_trade_payables", "trade_and_non_trade_receivables", ] ``` ```python Cash Flow Statement theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid line line_items for the cash flow statement line_items = [ "business_acquisitions_and_disposals", "capital_expenditure", "change_in_cash_and_equivalents", "depreciation_and_amortization", "dividends_and_other_cash_distributions", "effect_of_exchange_rate_changes", "investment_acquisitions_and_disposals", "issuance_or_purchase_of_equity_shares", "issuance_or_repayment_of_debt_securities", "net_cash_flow_from_financing", "net_cash_flow_from_investing", "net_cash_flow_from_operations", "share_based_compensation", ] ``` ### Code Example ```python Financials Search theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests import json # Add your API key to the headers headers = { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" } # Prepare the request body body = { "period": "ttm", "tickers": ["NVDA", "AAPL"], "limit": 1, "line_items": [ "net_income", "total_debt" ] } # Create the URL url = 'https://api.financialdatasets.ai/financials/search/line-items' # Make API request response = requests.post(url, headers=headers, data=json.dumps(body)) # Parse search results, which are ordered by report period, newest to oldest search_results = response.json().get('search_results') # Print the results for result in search_results: print(f"Ticker: {result['ticker']}") print(f"Report Period: {result['report_period']}") print(f"Revenue: ${result['net_income']:,.0f}") print(f"Total Debt: ${result['total_debt']:,.0f}") print("---") ``` # Stock Screener Source: https://docs.financialdatasets.ai/api/financials/search-screener POST /financials/search/screener Screen and filter stocks by financial metrics like revenue, net income, P/E ratio, and more. ### Overview This endpoint lets you screen for companies that match your investment criteria by filtering on fundamental financial metrics and company attributes. You can combine multiple conditions—such as revenue thresholds, valuation ratios, profitability margins, debt levels, and industry/sector classifications—to screen for stocks that fit your strategy. All available metrics are listed in the [Available Filters](#available-filters) section below. For example, you can search for companies with revenue greater than \$100 million and a P/E ratio less than 20 with the following request body: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} // Send JSON Request { "filters": [ { "field": "revenue", "operator": "gt", "value": 100000000 }, { "field": "pe_ratio", "operator": "lt", "value": 20 } ] } ``` And receive the following search results, sorted by ticker: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} // Receive JSON Response { "results": [ { "ticker": "AA", "pe_ratio": 8.37, "report_period": "2025-09-30", "currency": "USD", "revenue": 12868000000.0 }, { "ticker": "AAL", "pe_ratio": 14.65, "report_period": "2025-09-30", "currency": "USD", "revenue": 54294000000.0 } ] } ``` ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 17,000+ | Latest | Within 1 second | ### Request Body A JSON object with the following properties: * `filters` (array, required): An array of filter objects to apply. * `limit` (integer, optional): The maximum number of results to return. Defaults to 10. **Filters** Each filter object in the `filters` array must contain: * `field` (string): The financial metric or company attribute to filter on. * `operator` (string): The comparison operator. * `value` (integer, decimal, or string): The value to compare against. Use strings for company fields like `sector` and `industry`. **Operators** The `operator` must be one of the following: * `"eq"` (equal to) * `"gt"` (greater than) * `"gte"` (greater than or equal to) * `"lt"` (less than) * `"lte"` (less than or equal to) * `"in"` (value is in the provided array) ### Available Filters You can filter by any of the fields below, which are grouped by their source. You can also fetch these programmatically via `GET /financials/search/screener/filters`. ```python Income Statement theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid filter fields for the income statement fields = [ "consolidated_income", "cost_of_revenue", "dividends_per_common_share", "earnings_per_share", "earnings_per_share_diluted", "ebit", "ebit_usd", "earnings_per_share_usd", "gross_profit", "income_tax_expense", "interest_expense", "net_income", "net_income_common_stock", "net_income_common_stock_usd", "net_income_discontinued_operations", "net_income_non_controlling_interests", "operating_expense", "operating_income", "preferred_dividends_impact", "research_and_development", "revenue", "revenue_usd", "selling_general_and_administrative_expenses", "weighted_average_shares", "weighted_average_shares_diluted", ] ``` ```python Balance Sheet theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid filter fields for the balance sheet fields = [ "accumulated_other_comprehensive_income", "cash_and_equivalents", "cash_and_equivalents_usd", "current_assets", "current_debt", "current_investments", "current_liabilities", "deferred_revenue", "deposit_liabilities", "goodwill_and_intangible_assets", "inventory", "investments", "non_current_assets", "non_current_debt", "non_current_investments", "non_current_liabilities", "outstanding_shares", "property_plant_and_equipment", "retained_earnings", "shareholders_equity", "shareholders_equity_usd", "tax_assets", "tax_liabilities", "total_assets", "total_debt", "total_debt_usd", "total_liabilities", "trade_and_non_trade_payables", "trade_and_non_trade_receivables", ] ``` ```python Cash Flow Statement theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid filter fields for the cash flow statement fields = [ "business_acquisitions_and_disposals", "capital_expenditure", "change_in_cash_and_equivalents", "depreciation_and_amortization", "dividends_and_other_cash_distributions", "effect_of_exchange_rate_changes", "investment_acquisitions_and_disposals", "issuance_or_purchase_of_equity_shares", "issuance_or_repayment_of_debt_securities", "net_cash_flow_from_financing", "net_cash_flow_from_investing", "net_cash_flow_from_operations", "share_based_compensation", "net_income", "free_cash_flow", "ending_cash_balance", "property_plant_and_equipment", ] ``` ```python Financial Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid filter fields for financial metrics fields = [ "stock_price", "market_cap", "enterprise_value", "pe_ratio", "pb_ratio", "ps_ratio", "ev_ebitda_ratio", "ev_revenue_ratio", "free_cash_flow_yield", "peg_ratio", "gross_margin", "operating_margin", "net_margin", "return_on_equity", "return_on_assets", "return_on_invested_capital", "asset_turnover", "inventory_turnover", "receivables_turnover", "days_sales_outstanding", "operating_cycle", "working_capital_turnover", "current_ratio", "quick_ratio", "cash_ratio", "operating_cash_flow_ratio", "debt_to_equity", "debt_to_assets", "interest_coverage", "revenue_growth", "earnings_growth", "book_value_growth", "earnings_per_share_growth", "free_cash_flow_growth", "operating_income_growth", "ebitda_growth", "dividend_yield", "payout_ratio", "earnings_per_share", "book_value_per_share", "free_cash_flow_per_share", ] ``` ```python Company theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # List of valid filter fields for company attributes # These fields only support "eq" and "in" operators # Values are case-insensitive (e.g. "health care" matches "Health Care") fields = [ "industry", "sector", ] ``` **Margins and ratios** (e.g. `gross_margin`, `operating_margin`, `net_margin`, `revenue_growth`) are stored as decimals, not percentages. For example, a 10% operating margin is `0.10`, not `10`. **Valuation ratios** like `pe_ratio` can be negative for companies with negative earnings. To screen for a "reasonable" P/E range, use two filters — e.g. `pe_ratio gte 0` and `pe_ratio lte 25`. **Company fields** (`sector`, `industry`) accept string values and only support the `eq` and `in` operators. Values are case-insensitive — e.g. `"health care"` matches `"Health Care"`. These fields use the [GICS](https://en.wikipedia.org/wiki/Global_Industry_Classification_Standard) (Global Industry Classification Standard) classification system. ### Code Example ```python Filter by Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests import json headers = { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" } body = { "limit": 5, "currency": "USD", "filters": [ { "field": "pe_ratio", # from financial metrics "operator": "lt", "value": 20 }, { "field": "revenue", # from income statement "operator": "gte", "value": 1000000000 }, { "field": "total_debt", # from balance sheet "operator": "lt", "value": 500000000 }, ] } url = 'https://api.financialdatasets.ai/financials/search/screener' response = requests.post(url, headers=headers, data=json.dumps(body)) results = response.json().get('results') for result in results: print(f"Ticker: {result['ticker']}") print(f"P/E Ratio: {result.get('pe_ratio')}") print(f"Revenue: {result.get('revenue')}") print(f"Total Debt: {result.get('total_debt')}") print("---") ``` ```python Filter by Sector + Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests import json headers = { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" } body = { "limit": 10, "filters": [ { "field": "sector", # from company attributes "operator": "eq", "value": "Health Care" }, { "field": "market_cap", # from financial metrics "operator": "lt", "value": 5000000000 }, { "field": "revenue_growth", # from financial metrics "operator": "gt", "value": 0.10 }, ] } url = 'https://api.financialdatasets.ai/financials/search/screener' response = requests.post(url, headers=headers, data=json.dumps(body)) results = response.json().get('results') for result in results: print(f"Ticker: {result['ticker']}") print(f"Market Cap: {result.get('market_cap')}") print(f"Revenue Growth: {result.get('revenue_growth')}") print("---") ``` # Funds (by holding) Source: https://docs.financialdatasets.ai/api/index-funds/holding GET /index-funds Find which ETFs and index funds hold a given security, and at what weight, sourced direct from SEC fund holdings filings. ### Overview Give us a security ticker, get the funds that hold it, each with that fund's weight in the security. Results are sorted by weight descending, with a security header that echoes the queried ticker and the total number of funds. Use this to answer "which ETFs hold AAPL, and how much?" for exposure look-through, crowding, and flow analysis. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Securities | Years of Coverage | Updated | | ---------- | ----------------- | ------- | | 4,500+ | 5+ years | Daily | ### The "current" definition This endpoint returns the funds whose **most recent filing** holds the security. Funds that held it in an earlier filing but no longer report it are excluded. This is the strict "currently holds" view. ### Matching `holding` is a security **ticker** (e.g., `AAPL`), so this endpoint covers exchange-listed equities. ### Find available tickers The funds available in the API are listed by the same helper endpoint used by the by-fund query: ```python Tickers theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # free endpoint, no API key required url = 'https://api.financialdatasets.ai/index-funds/tickers/' response = requests.get(url) tickers = response.json().get('tickers') print(f'{len(tickers)} funds available') ``` ### Filtering the Data `holding` is required. By default, `limit` is `50` (max `1000`). Use `offset` to page through the funds. A security that no fund currently holds returns an empty `funds` array (not an error). ### Examples ```python Funds holding a security theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params holding = 'AAPL' # held security ticker limit = 100 # number of funds to return # create the URL url = ( f'https://api.financialdatasets.ai/index-funds/' f'?holding={holding}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse funds from the response funds = response.json().get('funds') ``` # Holdings (by fund) Source: https://docs.financialdatasets.ai/api/index-funds/ticker GET /index-funds Get an ETF or index fund's holdings and each position's weight, sourced direct from SEC fund holdings filings. ### Overview Give us a fund ticker, get its full list of holdings and each position's percent of net assets. Constituents are returned sorted by weight descending, with a fund header that carries the as-of period and coverage counts. Use this to answer "what's in SPY, and at what weight?" for index replication, exposure analysis, and overlap checks. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Funds | Years of Coverage | Updated | | ----- | ----------------- | ------- | | 500+ | 5+ years | Daily | ### The "latest" definition Without an `as_of` filter, this endpoint returns the fund's **most recent filing**. To reconstruct a historical composition, pass `as_of=YYYY-MM-DD` and the response is the composition in effect on or before that date. ### All holdings, labeled Every position is returned, including bonds, derivatives, and cash, each labeled with an `asset_class` (`equity`, `bond`, or `other`). Identifiers (`cusip`, `isin`, `name`) are included when available; `ticker` is `null` for securities without a US listing (e.g., many bonds and foreign holdings). To narrow the list, pass `asset_class=equity` or `asset_class=bond`. ### Find available tickers To discover which funds are available, hit the helper endpoint: ```python Tickers theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # free endpoint, no API key required url = 'https://api.financialdatasets.ai/index-funds/tickers/' response = requests.get(url) tickers = response.json().get('tickers') print(f'{len(tickers)} funds available') ``` ### Filtering the Data `ticker` is required. Optional filters: * `as_of` — the composition in effect on/before this date (YYYY-MM-DD). Defaults to the latest filing. * `asset_class` — `equity` or `bond`. Defaults to all holdings. By default, `limit` is `50` (max `1000`). Use `offset` to page through a fund's constituents. ### Examples ```python Latest holdings theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'SPY' # fund ticker limit = 50 # number of holdings to return # create the URL url = ( f'https://api.financialdatasets.ai/index-funds/' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse holdings from the response holdings = response.json().get('holdings') ``` ```python As-of date + equities only theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'SPY' as_of = '2023-12-31' # composition in effect on/before this date asset_class = 'equity' # equities only # create the URL url = ( f'https://api.financialdatasets.ai/index-funds/' f'?ticker={ticker}' f'&as_of={as_of}' f'&asset_class={asset_class}' ) # make API request response = requests.get(url, headers=headers) # parse holdings from the response holdings = response.json().get('holdings') ``` # Insider Ownership Source: https://docs.financialdatasets.ai/api/insider-ownership GET /insider-ownership See what company insiders actually own, from SEC Forms 3 and 5. Initial ownership statements and annual holdings for officers, directors, and 10% owners. ### Overview The insider ownership API gives you the ownership statements of public company insiders: what CEOs, CFOs, directors, and 10% owners actually **hold**, not just what they traded. It is sourced from SEC **Form 3** (an insider's initial statement of ownership, filed when they become an insider) and **Form 5** (the annual statement). It complements the [insider trades API](/api/insider-trades), which covers the buys and sells in between: trades are the events, ownership statements are the state. You can answer questions like: * What did a new director own on the day they joined the board? * What positions does an insider report in their annual statement, including options and RSUs? * Which insiders hold their shares indirectly, through trusts or LLCs? Positions are returned as reported per filing (point-in-time statements), newest filings first. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Companies | Insiders | History | Updated | | --------- | -------- | ------------------ | ------- | | 6,500+ | 40,000+ | Since January 2021 | Daily | ### Available Tickers You can fetch a list of companies with insider ownership statements with a `GET` request to: [https://api.financialdatasets.ai/insider-ownership/tickers/](https://api.financialdatasets.ai/insider-ownership/tickers/) ### Available Insiders You can fetch a list of insider names for a given ticker with a `GET` request to: [https://api.financialdatasets.ai/insider-ownership/names/?ticker=AAPL](https://api.financialdatasets.ai/insider-ownership/names/?ticker=AAPL) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker` (required), plus `name`, `form_type`, `limit`, and `filing_date`. **Note**: by default, `limit` is `10` (max `1000`), `name` is `null`, and `form_type` is `null`. The `name` parameter matches insider names (case-insensitive contains). You can get the list of available names for a ticker from the `/names` endpoint above. The `form_type` parameter filters to `3` (initial ownership statements), `5` (annual statements), or their amendments `3/A` and `5/A`. The `filing_date` parameter is used to filter by when filings were submitted. For example, you can include filters like `filing_date_lte=2026-06-30` and `filing_date_gte=2026-01-01` to get statements filed in the first half of 2026. The available `filing_date` operations are: * `filing_date_lte` * `filing_date_lt` * `filing_date_gte` * `filing_date_gt` * `filing_date` ### Example ```python Insider Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker limit = 50 # number of rows to return # create the URL url = ( f'https://api.financialdatasets.ai/insider-ownership' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse insider_ownership from the response insider_ownership = response.json().get('insider_ownership') ``` ### Example (with name) ```python Insider Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker name = 'cook' # insider name (case-insensitive contains) # create the URL url = ( f'https://api.financialdatasets.ai/insider-ownership' f'?ticker={ticker}' f'&name={name}' ) # make API request response = requests.get(url, headers=headers) # parse insider_ownership from the response insider_ownership = response.json().get('insider_ownership') ``` ### Example (initial statements only) ```python Insider Ownership theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # stock ticker form_type = '3' # Form 3: what a new insider owned on day one # create the URL url = ( f'https://api.financialdatasets.ai/insider-ownership' f'?ticker={ticker}' f'&form_type={form_type}' ) # make API request response = requests.get(url, headers=headers) # parse insider_ownership from the response insider_ownership = response.json().get('insider_ownership') ``` # Insider Trades Source: https://docs.financialdatasets.ai/api/insider-trades GET /insider-trades Get SEC Form 4 insider trading data for any US stock. Includes buy/sell transactions by officers and directors. ### Overview The insider trades API lets you access the stock buys and sales of public company insiders like CEOs, CFOs, and Directors. In addition to the stock buys and sales, you can also access the current ownership stakes of insiders. This data is useful for understanding the sentiment of company insiders. For example, you can answer questions like: * How many shares of Nvidia does Jensen Huang own? * How many shares of Microsoft did Satya Nadella buy last quarter? * How many shares of Apple has Tim Cook sold over the past year? To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ----------------- | | 8,200+ | 15+ years | Within 10 seconds | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/insider-trades/tickers/](https://api.financialdatasets.ai/insider-trades/tickers/) ### Available Insiders You can fetch a list of available insider names for a given ticker with a `GET` request to: [https://api.financialdatasets.ai/insider-trades/names/?ticker=AAPL](https://api.financialdatasets.ai/insider-trades/names/?ticker=AAPL) ### Available Transaction Types You can fetch a list of available transaction types with a `GET` request to: [https://api.financialdatasets.ai/insider-trades/transaction-types/](https://api.financialdatasets.ai/insider-trades/transaction-types/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data You can filter the data by `ticker`, `name`, `transaction_type`, `form_type`, `limit`, and `filing_date`. **Note**: `ticker` is required. By default, `limit` is `100`, `name` is `null`, `transaction_type` is `null`, `form_type` is `null`, and `filing_date` is `null`. The `name` parameter is used to filter trades by a specific insider. You can get the list of available names for a ticker from the `/names` endpoint above. The `transaction_type` parameter is used to filter trades by type (e.g., "Open market sale", "Gift"). You can get the list of available transaction types from the `/transaction-types` endpoint above. The `form_type` parameter filters by SEC form: `4` for trade reports, `5` for transactions reported on annual statements, or their amendments `4/A` and `5/A`. Each item also carries its `form_type`. The `limit` parameter is used to specify the number of trades to return. The maximum value is `1000`. The `filing_date` parameter is used to specify the date of the trades. For example, you can include filters like `filing_date_lte=2024-09-30` and `filing_date_gte=2024-01-01` to get trades between January 1, 2024 and September 30, 2024. The available `filing_date` operations are: * `filing_date_lte` * `filing_date_lt` * `filing_date_gte` * `filing_date_gt` * `filing_date` ### Example ```python Insider Trades theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker limit = 100 # number of trades to return # create the URL url = ( f'https://api.financialdatasets.ai/insider-trades' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse insider_trades from the response insider_trades = response.json().get('insider_trades') ``` ### Example (with name) ```python Insider Trades theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker name = 'Jen Hsun Huang' # insider name # create the URL url = ( f'https://api.financialdatasets.ai/insider-trades' f'?ticker={ticker}' f'&name={name}' ) # make API request response = requests.get(url, headers=headers) # parse insider_trades from the response insider_trades = response.json().get('insider_trades') ``` ### Example (with transaction\_type) ```python Insider Trades theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' # stock ticker transaction_type = 'Open market sale' # transaction type # create the URL url = ( f'https://api.financialdatasets.ai/insider-trades' f'?ticker={ticker}' f'&transaction_type={transaction_type}' ) # make API request response = requests.get(url, headers=headers) # parse insider_trades from the response insider_trades = response.json().get('insider_trades') ``` ### Example (with filing\_date) ```python Insider Trades theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'NVDA' filing_date_lte = '2024-01-01' # end date filing_date_gte = '2020-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/insider-trades' f'?ticker={ticker}' f'&filing_date_lte={filing_date_lte}' f'&filing_date_gte={filing_date_gte}' ) # make API request response = requests.get(url, headers=headers) # parse insider_trades from the response insider_trades = response.json().get('insider_trades') ``` # Holdings (by investor) Source: https://docs.financialdatasets.ai/api/institutional-holdings/investor GET /institutional-holdings Get the 13F portfolio of any institutional investment manager, by SEC CIK. ### Overview Get the full equity portfolio of any institutional investment manager that files SEC Form 13F (managers overseeing \$100M+ in assets). Data comes directly from SEC Form 13F filings, including per-position share counts, market values, voting authority splits, and subsidiary-manager breakdowns. We preserve the full SEC filing fidelity: when a manager splits voting authority across subsidiaries (e.g., Berkshire across National Indemnity / GEICO), each split is exposed in a `subsidiaries` array on the position. You can use this data to: * Track every position held by a specific investment manager * Compare position changes quarter-over-quarter * Surface concentration, voting structure, and amendment activity Note: Form 13F filings have a 45-day lag from quarter end and only include long positions in SEC-registered securities. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ------- | | 18,000+ | 5+ years | Daily | ### Find an investor's CIK Investors are queried by `filer_cik`, not by name. To discover a CIK, hit the helper endpoint: ```python Investors theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # free endpoint, no API key required url = 'https://api.financialdatasets.ai/institutional-holdings/investors/?name=BERK' response = requests.get(url) # each item is { "cik": "...", "name": "..." } for investor in response.json().get('investors'): print(investor['cik'], investor['name']) ``` Pass `?name=PREFIX` to filter to filers whose names start with that prefix (case-insensitive). Without `name`, the endpoint returns the first 100 filers alphabetically. **CIKs can change over time.** The SEC sometimes renames or restructures filer entities, so an investor's CIK may not be stable across years. The `/investors` lookup always returns the active CIK for the entity currently filing under that name, so prefer it over hard-coding CIKs from old documents. ### Filtering the Data `filer_cik` is required. By default, the response is the filer's **most recent 13F**. To see history, add `report_period` filters: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` For example, `report_period_gte=2024-01-01&report_period_lte=2025-12-31` returns every position the filer reported across that window. By default, `limit` is `10` (max `200`). ### Subsidiaries When a 13F filer reports the same security across multiple voting-authority splits (e.g., parent + subsidiary advisors), the top-level position aggregates the splits and a `subsidiaries` array preserves each underlying row. The `subsidiaries` field is omitted when there is only one underlying row. ### Examples ```python Latest portfolio theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params filer_cik = '0001067983' # Berkshire Hathaway's CIK limit = 100 # number of positions to return # create the URL url = ( f'https://api.financialdatasets.ai/institutional-holdings/' f'?filer_cik={filer_cik}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse institutional_holdings from the response institutional_holdings = response.json().get('institutional_holdings') ``` ```python Historical range theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params filer_cik = '0001067983' limit = 200 report_period_lte = '2025-12-31' # end date report_period_gte = '2024-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/institutional-holdings/' f'?filer_cik={filer_cik}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse institutional_holdings from the response institutional_holdings = response.json().get('institutional_holdings') ``` # Owners (by ticker) Source: https://docs.financialdatasets.ai/api/institutional-holdings/ticker GET /institutional-holdings Get the institutional investors who currently hold a given stock, sourced direct from SEC 13F filings. ### Overview Get the institutional investors who currently hold a given ticker, sorted by position size. Pulled directly from SEC Form 13F filings; results are sorted by position value descending. Use this to answer "who currently owns AAPL?" and at what size, with one row per filer and full subsidiary detail preserved. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ------- | | 18,000+ | 5+ years | Daily | ### The "current" definition Without a `report_period` filter, this endpoint returns one position per institutional filer **whose most recent 13F currently includes the ticker**. Filers who held the ticker historically but dropped it in their latest 13F are excluded. This is the strict "current holders" view. If you need historical snapshots, pass `report_period` filters (see below) to opt into the historical view. ### Find available tickers To discover which tickers appear across 13F filings, hit the helper endpoint: ```python Tickers theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # free endpoint, no API key required url = 'https://api.financialdatasets.ai/institutional-holdings/tickers/' response = requests.get(url) tickers = response.json().get('tickers') print(f'{len(tickers)} tickers held by 13F filers') ``` ### Filtering the Data `ticker` is required. By default, the response is the strict "currently owns" view described above. To see historical holders, pass `report_period` filters: * `report_period_lte` * `report_period_lt` * `report_period_gte` * `report_period_gt` * `report_period` When any `report_period` filter is provided, the endpoint returns every matching row in the period range (no current-owners filter is applied). By default, `limit` is `10` (max `200`). ### Subsidiaries When a 13F filer reports the same security across multiple voting-authority splits (e.g., parent + subsidiary advisors), the top-level position aggregates the splits and a `subsidiaries` array preserves each underlying row. The `subsidiaries` field is omitted when there is only one underlying row. ### Examples ```python Current holders theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # held security ticker limit = 100 # number of holders to return # create the URL url = ( f'https://api.financialdatasets.ai/institutional-holdings/' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse institutional_holdings from the response institutional_holdings = response.json().get('institutional_holdings') ``` ```python Historical range theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' limit = 200 report_period_lte = '2025-12-31' # end date report_period_gte = '2024-01-01' # start date # create the URL url = ( f'https://api.financialdatasets.ai/institutional-holdings/' f'?ticker={ticker}' f'&limit={limit}' f'&report_period_lte={report_period_lte}' f'&report_period_gte={report_period_gte}' ) # make API request response = requests.get(url, headers=headers) # parse institutional_holdings from the response institutional_holdings = response.json().get('institutional_holdings') ``` # IPOs Source: https://docs.financialdatasets.ai/api/ipos GET /ipos Track upcoming IPOs from SEC registration statements (Form S-1), including full pre-IPO financial statements for IPO-grade companies. ### Overview The IPOs API gives you a real-time feed of SEC **registration statements** (Form S-1 and its amendments, Form S-1/A): the filings companies make before going public. Every filing is classified as one of `ipo` (a real operating company registering to list on an exchange), `shell_company`, `spac`, `resale`, or `other`, with structured metadata from the cover page: the proposed ticker, exchange, and expected offering price or price range. For IPO-grade filings, we extract the complete pre-IPO financial statements from the prospectus: income statements, balance sheets, and cash flow statements, including interim periods. These are embedded directly in each feed item under `financials`, in the exact same shape as our [financial statements API](/api/financials/all-financial-statements). You can answer questions like: * Which companies filed to go public this week? * What are the revenue, margins, and cash burn of a company before it IPOs? * What ticker and exchange will a company list under, and at what expected price? Filings are returned newest first. For extracted IPO-grade filings, the same pre-IPO financial statements are also available under the company's proposed ticker via the standard financials endpoints: [income statements](/api/financials/income-statements), [balance sheets](/api/financials/balance-sheets), and [cash flow statements](/api/financials/cash-flow-statements). To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Filings | History | Updated | | ---------------------------- | --------------- | --------- | | Every SEC Form S-1 and S-1/A | Since July 2026 | Real-time | ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `classification` and `limit` to filter the data. 3. Execute the API request. ### Filtering the Data No parameters are required: by default, the API returns the latest filings across all companies. You can filter by `ticker`, `cik`, `classification`, `limit`, and `filing_date`. **Note**: by default, `limit` is `10` (max `100`). The `ticker` parameter matches the proposed ticker from the filing's cover page. The `cik` parameter matches the SEC Central Index Key of the filer, with or without leading zeros. The `classification` parameter filters to `ipo`, `shell_company`, `spac`, `resale`, or `other`. The `filing_date` parameter is used to filter by when filings were submitted. For example, you can include filters like `filing_date_lte=2026-06-30` and `filing_date_gte=2026-01-01` to get filings from the first half of 2026. The available `filing_date` operations are: * `filing_date_lte` * `filing_date_lt` * `filing_date_gte` * `filing_date_gt` * `filing_date` Each item includes a `status` field describing where the filing is in our processing pipeline. A filing appears on the feed as soon as it is classified; `financials` is `null` until extraction completes, at which point `status` is `COMPLETED` and `financials` contains the full statement arrays. ### Examples ```python Latest Filings theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params limit = 25 # number of filings to return # create the URL url = ( f'https://api.financialdatasets.ai/ipos' f'?limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse ipos from the response ipos = response.json().get('ipos') ``` ```python IPO-Grade Only theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params classification = 'ipo' # real operating companies going public # create the URL url = ( f'https://api.financialdatasets.ai/ipos' f'?classification={classification}' ) # make API request response = requests.get(url, headers=headers) # parse ipos from the response ipos = response.json().get('ipos') ``` ```python By Ticker theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'SPCX' # proposed ticker from the filing cover # create the URL url = ( f'https://api.financialdatasets.ai/ipos' f'?ticker={ticker}' ) # make API request response = requests.get(url, headers=headers) # parse ipos and the embedded financial statements ipos = response.json().get('ipos') financials = ipos[0].get('financials') if ipos else None ``` ```python By Filing Date theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params filing_date_gte = '2026-07-01' # filings from July 2026 onward # create the URL url = ( f'https://api.financialdatasets.ai/ipos' f'?filing_date_gte={filing_date_gte}' ) # make API request response = requests.get(url, headers=headers) # parse ipos from the response ipos = response.json().get('ipos') ``` # Guidance Source: https://docs.financialdatasets.ai/api/kpi/guidance GET /kpi/guidance Get forward guidance from earnings releases. ### Overview The KPI Guidance API returns structured forward guidance extracted from earnings releases. Guidance is delivered as ranges (low/high), point estimates, or directional signals. Examples: operating margin guidance of 6-8%, EPS guidance of $1.00-$1.50, capacity growth of flat YoY, fuel price assumptions, FFO per share outlook. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ----------------- | | 600+ | 3+ years | Within 10 seconds | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/kpi/guidance/tickers/](https://api.financialdatasets.ai/kpi/guidance/tickers/) ### Getting Started 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the required query param `ticker`. 3. Execute the API request. ### Filtering the Data | Parameter | Required | Description | | ------------------- | -------- | ------------------------------------------------------------------------------------------------ | | `ticker` | Yes | Stock ticker symbol (e.g., `DAL`, `PLD`) | | `metric_name` | No | Filter to a specific metric (snake\_case, e.g., `revenue`, `operating_margin`; case-insensitive) | | `period` | No | `quarterly` (default) or `annual` | | `report_period_gte` | No | Only return guidance on or after this date (`YYYY-MM-DD`) | | `report_period_lte` | No | Only return guidance on or before this date (`YYYY-MM-DD`) | | `limit` | No | Number of periods to return (default: 4, max: 50) | ### Example ```python KPI Guidance theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ticker = "DAL" url = f"https://api.financialdatasets.ai/kpi/guidance?ticker={ticker}" response = requests.get(url, headers=headers) data = response.json() kpi_guidance = data["kpi_guidance"] ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "kpi_guidance": [ { "ticker": "DAL", "metric_name": "operating_margin", "unit": "%", "period": "Q2 2026", "period_type": "quarterly", "low": 6.0, "high": 8.0, "change_direction": "initiated", "source_text": "Operating margin guidance of 6-8%", "source_url": "https://www.sec.gov/Archives/..." }, { "ticker": "DAL", "metric_name": "earnings_per_share_diluted", "unit": "dollars", "period": "Q2 2026", "period_type": "quarterly", "low": 1.0, "high": 1.5, "change_direction": "initiated", "source_text": "Earnings per share of $1.00-$1.50", "source_url": "https://www.sec.gov/Archives/..." } ] } ``` ### Response Fields | Field | Type | Description | | ------------------ | ------ | ---------------------------------------------------------------------------------- | | `low` | number | Low end of the guidance range | | `high` | number | High end of the guidance range | | `point_estimate` | number | Single-point guidance (when no range is given) | | `prior_value` | number | Prior guidance value (for revisions) | | `change_direction` | string | Direction of guidance: `raised`, `lowered`, `maintained`, `initiated`, `withdrawn` | | `raw_text` | string | Original guidance text from the filing | ### Notes * Guidance periods are forward-looking (e.g., Q2 2026 guidance reported in a Q1 2026 filing). * The `source_url` links directly to the source document with text highlighting when available. # Metrics Source: https://docs.financialdatasets.ai/api/kpi/metrics GET /kpi/metrics Get operational key performance indicators from earnings releases. ### Overview The KPI Metrics API returns structured operational KPIs that are not available in standard financial statements. These are the metrics that drive investment theses: * **Airlines**: load factor, CASM-ex-fuel, passenger yield, revenue per ASM, fuel cost per gallon * **Banks**: CET1 ratio, net interest margin, efficiency ratio, ROTCE, trading revenue * **REITs**: FFO per share, same-store NOI growth, occupancy, lease spreads, cap rates * **Retail**: comparable store sales, e-commerce growth, membership revenue * **Semiconductors**: data center revenue, gaming revenue, automotive revenue Data is sourced from earnings releases, earnings call transcripts, and press releases. Each metric includes the source text and a direct link to the source document. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ----------------- | | 600+ | 3+ years | Within 10 seconds | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/kpi/metrics/tickers/](https://api.financialdatasets.ai/kpi/metrics/tickers/) ### Available Sectors You can fetch a list of available sectors with a `GET` request to: [https://api.financialdatasets.ai/kpi/metrics/sectors/](https://api.financialdatasets.ai/kpi/metrics/sectors/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the required query param `ticker`. 3. Execute the API request. ### Filtering the Data | Parameter | Required | Description | | ------------------- | -------- | ----------------------------------------------------------------------------------------------------- | | `ticker` | Yes | Stock ticker symbol (e.g., `DAL`, `JPM`) | | `metric_name` | No | Filter to a specific metric (e.g., `load_factor`, `cet1_ratio`) | | `period` | No | `quarterly` (default) or `annual` | | `report_period_gte` | No | Only return metrics on or after this date (`YYYY-MM-DD`) | | `report_period_lte` | No | Only return metrics on or before this date (`YYYY-MM-DD`) | | `limit` | No | Number of periods to return (default: 4, max: 50). Returns all metrics for the N most recent periods. | ### Example ```python KPI Metrics theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ticker = "DAL" url = f"https://api.financialdatasets.ai/kpi/metrics?ticker={ticker}" response = requests.get(url, headers=headers) data = response.json() kpi_metrics = data["kpi_metrics"] ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "kpi_metrics": [ { "ticker": "DAL", "metric_name": "load_factor", "value": 82.0, "unit": "%", "period": "Q4 2025", "period_type": "quarterly", "yoy_value": 84.0, "yoy_change_pct": -2.381, "source_text": "Passenger load factor", "source_url": "https://www.sec.gov/Archives/edgar/data/27904/000002790426000008/deltaairlinesannouncesdece.htm#:~:text=Passenger%20load%20factor,82" }, { "ticker": "DAL", "metric_name": "casm_ex_fuel", "value": 14.27, "unit": "cents", "period": "Q4 2025", "period_type": "quarterly", "yoy_value": 13.72, "yoy_change_pct": 4.01, "source_text": "CASM-Ex - see Note A (cents)", "source_url": "https://www.sec.gov/Archives/edgar/data/27904/000002790426000008/deltaairlinesannouncesdece.htm#:~:text=CASM-Ex%20-%20see%20Note%20A%20%28cents%29,14.27" }, { "ticker": "DAL", "metric_name": "passenger_yield", "value": 21.58, "unit": "cents", "period": "Q4 2025", "period_type": "quarterly", "source_text": "Passenger yield (cents)", "source_url": "https://www.sec.gov/Archives/edgar/data/27904/000002790426000008/deltaairlinesannouncesdece.htm#:~:text=Passenger%20yield%20%28cents%29,21.58" } ] } ``` ### Notes * The `source_url` links directly to the source document. When a text-level citation is available, the URL includes a fragment that highlights the source text in the browser. # Non-GAAP Metrics Source: https://docs.financialdatasets.ai/api/kpi/non-gaap GET /kpi/non-gaap Get non-GAAP financial metrics with GAAP reconciliation context. ### Overview The KPI Non-GAAP API returns adjusted financial metrics extracted from earnings releases, paired with their GAAP equivalents and the key adjustments between them. Examples: Adjusted EPS, Adjusted EBITDA, Free Cash Flow, Non-GAAP Operating Income, Core FFO, CASM-ex-fuel. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ----------------- | | 600+ | 3+ years | Within 10 seconds | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/kpi/non-gaap/tickers/](https://api.financialdatasets.ai/kpi/non-gaap/tickers/) ### Getting Started 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the required query param `ticker`. 3. Execute the API request. ### Filtering the Data | Parameter | Required | Description | | ------------------- | -------- | --------------------------------------------------------- | | `ticker` | Yes | Stock ticker symbol (e.g., `DAL`, `BAC`) | | `metric_name` | No | Filter to a specific metric | | `period` | No | `quarterly` (default) or `annual` | | `report_period_gte` | No | Only return metrics on or after this date (`YYYY-MM-DD`) | | `report_period_lte` | No | Only return metrics on or before this date (`YYYY-MM-DD`) | | `limit` | No | Number of periods to return (default: 4, max: 50) | ### Example ```python KPI Non-GAAP theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ticker = "DAL" url = f"https://api.financialdatasets.ai/kpi/non-gaap?ticker={ticker}" response = requests.get(url, headers=headers) data = response.json() kpi_non_gaap = data["kpi_non_gaap"] ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "kpi_non_gaap": [ { "ticker": "DAL", "metric_name": "Adjusted Operating Revenue", "value": 14200000000.0, "unit": "USD", "period": "Q1 2026", "period_type": "quarterly", "gaap_equivalent": "Total operating revenue", "key_adjustments": "Excludes third-party refinery sales of $1,654M", "source_text": "Adjusted operating revenue", "source_url": "https://www.sec.gov/Archives/..." }, { "ticker": "DAL", "metric_name": "Adjusted Diluted EPS", "value": 0.64, "unit": "USD per share", "period": "Q1 2026", "period_type": "quarterly", "gaap_equivalent": "Diluted (loss)/earnings per share", "key_adjustments": "Excludes MTM adjustments on investments, MTM adjustments and settlements on hedges", "source_text": "Adjusted diluted earnings per share", "source_url": "https://www.sec.gov/Archives/..." } ] } ``` ### Response Fields | Field | Type | Description | | ----------------- | ------ | -------------------------------------------------------------------------------------- | | `gaap_equivalent` | string | The GAAP line item this metric adjusts (e.g., "Total operating revenue", "Net income") | | `key_adjustments` | string | Description of the adjustments made (e.g., "Excludes restructuring charges of \$150M") | ### Notes * Non-GAAP metrics often include both current and prior-year values from the same filing. * The `source_url` links directly to the source document with text highlighting when available. # Historical Source: https://docs.financialdatasets.ai/api/macro/inflation/historical GET /macro/inflation Get monthly US consumer price index history since 1947: headline and core CPI plus food, energy, shelter, and services, with month-over-month and year-over-year changes. ### Overview The Inflation API lets you pull the monthly US Consumer Price Index (CPI) for one series at a time, from 1947 to today, with the month-over-month and year-over-year percent changes computed for you. We source the data directly from authoritative government sources. Values are index levels (1982-84 = 100); the changes are percentages. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | History | Series | Updated | | ------------- | ------ | ------- | | 1947 to today | 12 | Monthly | ### Series Six concepts, each seasonally adjusted (`_sa`) and not seasonally adjusted (`_nsa`): | Series | What it is | From | | ------------------------------------------------------------- | ------------------------------ | --------------------- | | `cpi_all_sa`, `cpi_all_nsa` | All items | 1947 | | `cpi_core_sa`, `cpi_core_nsa` | All items less food and energy | 1957 | | `cpi_food_sa`, `cpi_food_nsa` | Food | 1947 | | `cpi_energy_sa`, `cpi_energy_nsa` | Energy | 1957 | | `cpi_shelter_sa`, `cpi_shelter_nsa` | Shelter | 1953 | | `cpi_services_less_energy_sa`, `cpi_services_less_energy_nsa` | Services less energy services | 1957 (NSA), 1967 (SA) | You can fetch this list, with each series' first available month, with a free `GET` request to: [https://api.financialdatasets.ai/macro/inflation/series/](https://api.financialdatasets.ai/macro/inflation/series/) ### Reading the fields * `date` is the reference month as its first day: `2026-08-01` is the August 2026 print, which is published in mid September. It is not the release date. * `value` is the published index level. * `change_1m_pct` is the percent change from the prior month and `change_12m_pct` from the same month a year earlier, both rounded to one decimal. The headline "inflation rate" is `change_12m_pct` of `cpi_all_nsa`; the headline monthly figure is `change_1m_pct` of `cpi_all_sa`. * A field is `null` when the comparison month was not published. October 2025 is `null` in every series because no October 2025 CPI was published, so the November 2025 1-month change and the October 2026 12-month change are `null` too. * History is the latest published values. When a past month is revised, the stored value is replaced. ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the `series` parameter, which is required. Optionally add `start_date` and `end_date` (inclusive, `YYYY-MM-DD`; any day inside a month selects that month). With no dates you get the trailing five years. 3. Execute the API request. Rows come newest first in pages of up to 10. When more rows remain, the response includes a `next_page_url`; request it as-is to get the next page. See the [pagination guide](/guides/pagination). ### Example ```python Inflation theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set parameters series = 'cpi_all_sa' # required start_date = '2025-09-01' # optional end_date = '2026-08-31' # optional # create the URL with parameters url = ( f'https://api.financialdatasets.ai/macro/inflation' f'?series={series}' f'&start_date={start_date}' f'&end_date={end_date}' ) # make API request response = requests.get(url, headers=headers) # parse the observations from the response inflation = response.json().get('inflation') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "inflation": [ { "series": "cpi_all_sa", "date": "2026-08-01", "value": 334.131, "change_1m_pct": 0.4, "change_12m_pct": 3.4 } ] } ``` # Snapshot Source: https://docs.financialdatasets.ai/api/macro/inflation/snapshot GET /macro/inflation/snapshot Get the latest US consumer price index print for every series: headline and core CPI plus food, energy, shelter, and services, with month-over-month and year-over-year changes. ### Overview The Inflation Snapshot API returns the most recent month of every CPI series we track, twelve rows, each with the month-over-month and year-over-year percent changes computed for you. Pass `series` to get one row. We source the data directly from authoritative government sources. The snapshot refreshes the morning each month's figures are published. To receive each new month's print without polling, subscribe to the `inflation.created` [webhook](/webhooks/events). To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | History | Series | Updated | | ------------ | ------ | ------- | | Latest month | 12 | Monthly | ### Series Six concepts, each seasonally adjusted (`_sa`) and not seasonally adjusted (`_nsa`): `cpi_all`, `cpi_core`, `cpi_food`, `cpi_energy`, `cpi_shelter`, `cpi_services_less_energy`. The full list is one free `GET` request away: [https://api.financialdatasets.ai/macro/inflation/series/](https://api.financialdatasets.ai/macro/inflation/series/) ### Reading the fields * `date` is the reference month as its first day, not the release date. * `value` is the published index level (1982-84 = 100). * `change_1m_pct` and `change_12m_pct` are percent changes from the prior month and from a year earlier, rounded to one decimal. The headline "inflation rate" is `change_12m_pct` of `cpi_all_nsa`. * A change is `null` when the comparison month was not published (for example, October 2025). ### Getting Started There are only 2 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Execute the API request. Add `series` to get one series instead of all twelve. ### Example ```python Inflation Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # create the URL url = 'https://api.financialdatasets.ai/macro/inflation/snapshot' # make API request response = requests.get(url, headers=headers) # parse the latest prints from the response inflation = response.json().get('inflation') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "inflation": [ { "series": "cpi_all_sa", "date": "2026-08-01", "value": 334.131, "change_1m_pct": 0.4, "change_12m_pct": 3.4 }, { "series": "cpi_all_nsa", "date": "2026-08-01", "value": 334.98, "change_1m_pct": 0.3, "change_12m_pct": 3.4 } ] } ``` The live response has one row per series, twelve in total. # Historical Source: https://docs.financialdatasets.ai/api/macro/interest-rates/historical GET /macro/interest-rates Get historical US interest rate data including Federal Funds Rate, Treasury yields, and SOFR. ### Overview The Interest Rates API lets you pull historical published interest rate data for all major central banks in the world. We source our data directly from global central banks like the Federal Reserve, People's Bank of China, European Central Bank, Bank of Japan, and other major monetary authorities. The real-time interest rate data comes from official monetary policy announcements. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Central Banks | Years of Coverage | Updated | | ------------- | ----------------- | ------- | | 10 | 80+ years | Daily | ### Available Central Banks You can fetch a list of available central banks with a `GET` request to: [https://api.financialdatasets.ai/macro/interest-rates/banks/](https://api.financialdatasets.ai/macro/interest-rates/banks/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the `bank` parameter, which is required 3. Execute the API request. ### Example ```python Interest Rates theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set parameters bank = 'FED' # required start_date = '2000-01-01' # optional end_date = '2025-01-01' # optional # create the URL with parameters url = ( f'https://api.financialdatasets.ai/macro/interest-rates' f'?bank={bank}' f'&start_date={start_date}' f'&end_date={end_date}' ) # make API request response = requests.get(url, headers=headers) # parse snapshot from the response interest_rates = response.json().get('interest_rates') ``` # Snapshot Source: https://docs.financialdatasets.ai/api/macro/interest-rates/snapshot GET /macro/interest-rates/snapshot Get a real-time snapshot of current US interest rates including Fed Funds Rate, Treasury yields, and SOFR. ### Overview The Interest Rates Snapshot API lets you pull the latest published interest rate data for all major central banks in the world. We source our data directly from global central banks like the Federal Reserve, People's Bank of China, European Central Bank, Bank of Japan, and other major monetary authorities. The real-time interest rate data comes from official monetary policy announcements. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Central Banks | Years of Coverage | Updated | | ------------- | ----------------- | ------- | | 10 | Latest | Daily | ### Available Central Banks You can fetch a list of available central banks with a `GET` request to: [https://api.financialdatasets.ai/macro/interest-rates/banks/](https://api.financialdatasets.ai/macro/interest-rates/banks/) ### Getting Started There are only 2 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Execute the API request. ### Example ```python Interest Rates Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # create the URL url = 'https://api.financialdatasets.ai/macro/interest-rates/snapshot' # make API request response = requests.get(url, headers=headers) # parse snapshot from the response interest_rates = response.json().get('interest_rates') ``` # Historical Source: https://docs.financialdatasets.ai/api/macro/yield-curve/historical GET /macro/yield-curve Get the daily US Treasury par yield curve since 1990: 1-month to 30-year yields, one row per business day. ### Overview The Treasury Yields API lets you pull the daily US Treasury par yield curve, one row per business day with one key per tenor, from 1990 to today. We source the data directly from authoritative government sources. Values are par yields in percent. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | History | Tenors | Updated | | ------------- | ------ | ------- | | 1990 to today | 14 | Daily | ### Tenors Each row carries `date` plus these keys: `1_month`, `1_5_month`, `2_month`, `3_month`, `4_month`, `6_month`, `1_year`, `2_year`, `3_year`, `5_year`, `7_year`, `10_year`, `20_year`, `30_year`. A tenor is `null` when it was not published on that date. These gaps are real, not missing data: the 20-year is absent before October 1993, the 30-year is absent from February 2002 to February 2006, the 2-month starts in October 2018, the 4-month starts in October 2022, and the 1.5-month starts in 2025. Weekends and market holidays have no row. ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Optionally add `start_date` and `end_date` (inclusive, `YYYY-MM-DD`). With no dates you get the trailing year. 3. Execute the API request. Rows come newest first in pages of up to 100. When more rows remain, the response includes a `next_page_url`; request it as-is to get the next page. See the [pagination guide](/guides/pagination). ### Example ```python Treasury Yields theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set parameters start_date = '2026-01-01' # optional end_date = '2026-03-31' # optional # create the URL with parameters url = ( f'https://api.financialdatasets.ai/macro/yield-curve' f'?start_date={start_date}' f'&end_date={end_date}' ) # make API request response = requests.get(url, headers=headers) # parse the yield curves from the response yield_curve = response.json().get('yield_curve') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "yield_curve": [ { "date": "2026-01-02", "1_month": 3.72, "1_5_month": 3.71, "2_month": 3.66, "3_month": 3.65, "4_month": 3.62, "6_month": 3.58, "1_year": 3.47, "2_year": 3.47, "3_year": 3.55, "5_year": 3.74, "7_year": 3.95, "10_year": 4.19, "20_year": 4.81, "30_year": 4.86 } ] } ``` # Snapshot Source: https://docs.financialdatasets.ai/api/macro/yield-curve/snapshot GET /macro/yield-curve/snapshot Get the latest US Treasury par yield curve: 1-month to 30-year yields for the most recent business day. ### Overview The Treasury Yields Snapshot API returns the most recent business day's par yield curve as one object with one key per tenor. We source the data directly from authoritative government sources. The snapshot refreshes each evening after the day's final curve is published. To receive each new day's curve without polling, subscribe to the `yield_curve.created` [webhook](/webhooks/events). To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | History | Tenors | Updated | | ------------------- | ------ | ------- | | Latest business day | 14 | Daily | ### Tenors The object carries `date` plus these keys: `1_month`, `1_5_month`, `2_month`, `3_month`, `4_month`, `6_month`, `1_year`, `2_year`, `3_year`, `5_year`, `7_year`, `10_year`, `20_year`, `30_year`. A tenor is `null` when it was not published that day. ### Getting Started There are only 2 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Execute the API request. ### Example ```python Treasury Yields Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # create the URL url = 'https://api.financialdatasets.ai/macro/yield-curve/snapshot' # make API request response = requests.get(url, headers=headers) # parse the latest yield curve from the response yield_curve = response.json().get('yield_curve') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "yield_curve": { "date": "2026-01-02", "1_month": 3.72, "1_5_month": 3.71, "2_month": 3.66, "3_month": 3.65, "4_month": 3.62, "6_month": 3.58, "1_year": 3.47, "2_year": 3.47, "3_year": 3.55, "5_year": 3.74, "7_year": 3.95, "10_year": 4.19, "20_year": 4.81, "30_year": 4.86 } } ``` # Company News Source: https://docs.financialdatasets.ai/api/news/company api/news/openapi-company.json GET /news Get the latest news articles and press coverage for any US public company by stock ticker. ### Overview The Company News API lets you pull recent news articles for a given company by `ticker`. Our news articles are sourced from public RSS feeds. Looking for broad market news instead? Use the [Market News](/api/news/market) endpoint, which takes no `ticker`. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 10,000+ | 2+ years | Within 1 minute | ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the `ticker` query param for the company you want news about. Optionally add `limit` to control the number of results. 3. Execute the API request. ### Example ```python Company News theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' limit = 5 # optional, max is 10 # create the URL url = ( f'https://api.financialdatasets.ai/news' f'?ticker={ticker}' f'&limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse news from the response news = response.json().get('news') ``` # Market News Source: https://docs.financialdatasets.ai/api/news/market api/news/openapi-market.json GET /news Get the latest broad market-moving news. ### Overview The Market News API lets you pull recent broad market news. Articles cover AI, macro, rates, earnings, geopolitics, war, energy, crypto, and other market-moving topics. Looking for news about a single company? Use the [Company News](/api/news/company) endpoint, which takes a `ticker` query param. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------------- | | 10,000+ | 2+ years | Within 1 minute | ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Omit the `ticker` query param to get broad market news. Optionally add `limit` to control the number of results. 3. Execute the API request. ### Example ```python Market News theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # omit ticker to get broad market news limit = 10 # create the URL url = ( f'https://api.financialdatasets.ai/news' f'?limit={limit}' ) # make API request response = requests.get(url, headers=headers) # parse market news from the response news = response.json().get('news') ``` # Historical Source: https://docs.financialdatasets.ai/api/prices/historical GET /prices Get historical stock prices for any US ticker. Daily, weekly, monthly, or yearly OHLCV data. ### Overview The Prices API lets you pull end-of-day (EOD) historical prices for a given ticker like Apple, Microsoft, and more. You can get prices by the day, week, month, or year going back 3 years. The data is perfect for backtesting trading strategies, analyzing price patterns, rendering charts, and more. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | ---------- | | 15,000+ | 3+ years | End of day | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/prices/tickers/](https://api.financialdatasets.ai/prices/tickers/) ### Required Parameters * `ticker` — the stock ticker symbol (e.g., AAPL, NVDA) * `interval` — `day`, `week`, `month`, or `year` * `start_date` — start date in YYYY-MM-DD format * `end_date` — end date in YYYY-MM-DD format ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add the required query params: `ticker`, `interval`, `start_date`, and `end_date`. 3. Execute the API request. ### Example ```python Prices theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' interval = 'day' # possible values are {'day', 'week', 'month', 'year'} start_date = '2025-01-02' end_date = '2025-01-05' # create the URL url = ( f'https://api.financialdatasets.ai/prices/' f'?ticker={ticker}' f'&interval={interval}' f'&start_date={start_date}' f'&end_date={end_date}' ) # make API request response = requests.get(url, headers=headers) # parse prices from the response prices = response.json().get('prices') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "prices": [ { "ticker": "AAPL", "open": 243.85, "close": 243.36, "high": 244.15, "low": 241.91, "volume": 40230800, "time": "2025-01-02" }, { "ticker": "AAPL", "open": 243.36, "close": 245.00, "high": 245.55, "low": 242.80, "volume": 38420500, "time": "2025-01-03" }, ... ] } ``` # Market Snapshot Source: https://docs.financialdatasets.ai/api/prices/market-snapshot GET /prices/snapshot/market Get a real-time price snapshot for every actively traded US stock in a single request. ### Overview The Market Snapshot API returns real-time prices for the entire US market in a single call. Each snapshot includes the current price, day change, and day change percent. Requires an active subscription. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 13,000+ | Latest | Real-time | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/prices/snapshot/tickers/](https://api.financialdatasets.ai/prices/snapshot/tickers/) ### Getting Started 1. Add your API key to the header of the request as `X-API-KEY`. 2. Execute the API request. No query parameters are needed. ### Example ```python Market Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } url = "https://api.financialdatasets.ai/prices/snapshot/market" response = requests.get(url, headers=headers) snapshots = response.json().get("snapshots") ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "snapshots": [ { "ticker": "BIRD", "price": 15.26, "day_change": 12.77, "day_change_percent": 512.85, "time": "2026-04-15T22:06:27Z", "time_milliseconds": 1776290787600 }, { "ticker": "BDRX", "price": 3.29, "day_change": 0.04, "day_change_percent": 1.23, "time": "2026-04-15T22:06:25Z", "time_milliseconds": 1776290785553 }, { "ticker": "SKYQ", "price": 11.05, "day_change": 1.85, "day_change_percent": 20.11, "time": "2026-04-15T22:06:25Z", "time_milliseconds": 1776290785498 }, ... ] } ``` # Company Snapshot Source: https://docs.financialdatasets.ai/api/prices/snapshot GET /prices/snapshot Get the latest real-time stock price snapshot for any US ticker including open, high, low, and close. ### Overview The Snapshot API lets you pull a price snapshot for a given ticker. We cover all actively traded US stocks. To get started, please create an account and grab your API key at [financialdatasets.ai](https://financialdatasets.ai). You will use the API key to authenticate your API requests. ### Coverage | Tickers | Years of Coverage | Updated | | ------- | ----------------- | --------- | | 13,000+ | Latest | Real-time | ### Available Tickers You can fetch a list of available tickers with a `GET` request to: [https://api.financialdatasets.ai/prices/snapshot/tickers/](https://api.financialdatasets.ai/prices/snapshot/tickers/) ### Getting Started There are only 3 steps for making a successful API call: 1. Add your API key to the header of the request as `X-API-KEY`. 2. Add query params like `ticker` to filter the data. 3. Execute the API request. **Note**: You must provide the `ticker`. ### Example ```python Price Snapshot theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # add your API key to the headers headers = { "X-API-KEY": "your_api_key_here" } # set your query params ticker = 'AAPL' # create the URL url = ( f'https://api.financialdatasets.ai/prices/snapshot' f'?ticker={ticker}' ) # make API request response = requests.get(url, headers=headers) # parse snapshot from the response snapshot = response.json().get('snapshot') ``` # Data Provenance Source: https://docs.financialdatasets.ai/data-provenance Primary-source financial data with full provenance transparency. Financial Datasets is a **primary-source data provider** of SEC filing data. We collect, normalize, and serve SEC-sourced datasets ourselves - giving you a direct, auditable path from regulatory filings to API response. For market data such as stock prices, we partner with a leading licensed, institutional-grade data provider to ensure the same level of quality and reliability. This page details exactly where each category of data originates. ## Why Provenance Matters Institutional workflows demand auditability. When a model or trading signal is questioned, you need to trace every input back to its authoritative source. Opaque data supply chains introduce risk - you inherit unknown collection methodologies, latency, and error surfaces without visibility into any of it. Our architecture minimizes that risk. For SEC data, you get a direct, auditable path from source to API response. For market data, we vet and partner with institutional-grade providers so you always know where your data comes from. ## Data Sources ### Financial Statements & Fundamentals All financial statements - income statements, balance sheets, and cash flow statements - are sourced **directly from SEC filings** (10-K, 10-Q, 8-K, and related exhibits). We parse the original XBRL and HTML submissions, normalize line items across reporting standards, and deliver a clean, structured dataset spanning 30+ years. **Source:** U.S. Securities and Exchange Commission (SEC) EDGAR system ### SEC Filings Our SEC filings endpoints serve filing metadata, full-text content, and structured exhibits pulled **directly from EDGAR**. There is no intermediary between the SEC's public dissemination system and our API. **Source:** SEC EDGAR ### Insider Transactions Form 3, Form 4, and Form 5 filings are ingested **directly from SEC EDGAR** as they become available. We parse each filing into structured records with standardized fields for transaction type, share quantity, price, and ownership details. **Source:** SEC EDGAR ### Institutional Holdings 13F filings are sourced and parsed **directly from SEC EDGAR**, providing quarterly snapshots of institutional holders, position sizes, and portfolio changes. **Source:** SEC EDGAR ### Earnings Earnings data, including actuals, is derived **directly from SEC filings** and issuer disclosures. **Source:** SEC EDGAR and issuer publications ### Stock Prices Equity price data - including open, high, low, and close - is sourced via [Databento](https://databento.com), our market data partner. Databento delivers real-time and historical market data direct from colocation sites and is trusted by 3,000+ leading firms and high-growth startups. **Sources:** Databento ### Macroeconomic Data Macroeconomic series, including interest rates, the Treasury yield curve, and consumer prices, are sourced **directly from authoritative government sources**. We store the latest published values and refresh them daily, so revisions land without a special path. **Sources:** Authoritative government sources ### News Company news is sourced from **publicly available news feeds**. Articles are collected close to the point of publication and indexed against our company universe for precise ticker attribution. **Source:** Public news feeds ## Provenance Guarantees We maintain **full transparency** over every data source in our pipeline. This means: * **Full auditability** - every record traces to a named primary source or licensed data partner. * **Primary-source SEC data** - all SEC-derived datasets are collected and parsed by us directly from EDGAR, with no intermediary. * **Vetted market data partners** - where we use licensed data providers, we select institutional-grade partners and maintain full visibility into the data supply chain. * **Controlled latency** - we own the ingestion and processing path, so delays are measurable and within our SLA. * **Single point of accountability** - if something is wrong with the data, we own the fix end-to-end. ## Questions For due-diligence inquiries or detailed methodology documentation, contact us at [support@financialdatasets.ai](mailto:support@financialdatasets.ai). # How to Get Fundamentals Source: https://docs.financialdatasets.ai/guides/analyze-financial-statements-python Learn how to fetch and analyze income statements, balance sheets, and cash flow statements for any US stock using Python. Financial statements are the foundation of fundamental analysis. This guide shows you how to fetch income statements, balance sheets, and cash flow statements for any US public company using Python. ## Prerequisites * Python 3.7+ * A Financial Datasets API key ([sign up here](https://financialdatasets.ai)) * The `requests` library (`pip install requests`) ## Step 1: Set Up Authentication ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ``` ## Step 2: Fetch Income Statements Use the [Income Statements API](/api/financials/income-statements) to get revenue, expenses, and net income data. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ticker = "NVDA" period = "annual" # options: annual, quarterly, ttm limit = 5 # number of periods to return url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?ticker={ticker}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) income_statements = response.json().get("income_statements") for stmt in income_statements: print(f"{stmt['report_period']}: Revenue=${stmt['revenue']:,}, Net Income=${stmt['net_income']:,}") ``` ## Step 3: Fetch Balance Sheets Use the [Balance Sheets API](/api/financials/balance-sheets) to get assets, liabilities, and equity data. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/balance-sheets" f"?ticker={ticker}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) balance_sheets = response.json().get("balance_sheets") for stmt in balance_sheets: print(f"{stmt['report_period']}: Assets=${stmt['total_assets']:,}, Equity=${stmt['total_equity']:,}") ``` ## Step 4: Fetch Cash Flow Statements Use the [Cash Flow Statements API](/api/financials/cash-flow-statements) to get operating, investing, and financing cash flows. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/cash-flow-statements" f"?ticker={ticker}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) cash_flow_statements = response.json().get("cash_flow_statements") for stmt in cash_flow_statements: print(f"{stmt['report_period']}: Operating CF=${stmt['operating_cash_flow']:,}") ``` ## Step 5: Get All Statements in One Call Use the [All Financial Statements API](/api/financials/all-financial-statements) to fetch all three statement types in a single request. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials" f"?ticker={ticker}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) data = response.json() income_statements = data.get("income_statements") balance_sheets = data.get("balance_sheets") cash_flow_statements = data.get("cash_flow_statements") ``` ## Filtering by Date Range Use `report_period` parameters to get statements within a specific date range: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?ticker=NVDA" f"&period=quarterly" f"&limit=100" f"&report_period_gte=2023-01-01" f"&report_period_lte=2024-12-31" ) ``` Available date filters: `report_period`, `report_period_lt`, `report_period_lte`, `report_period_gt`, `report_period_gte`. ## Available Tickers Fetch the list of tickers with financial statement coverage: ``` GET https://api.financialdatasets.ai/financials/income-statements/tickers/ ``` Coverage includes 27,000+ US tickers with 30+ years of history. ## Next Steps * [Income Statements API Reference](/api/financials/income-statements) — full parameter documentation * [Balance Sheets API Reference](/api/financials/balance-sheets) — all available fields * [Financial Metrics API](/api/financial-metrics/historical) — pre-calculated ratios like P/E, ROE, and EV/EBITDA * [SEC Filings Guide](/guides/search-sec-filings-python) — access the source documents behind the numbers # How to Get Stock Prices Source: https://docs.financialdatasets.ai/guides/get-stock-prices-python Learn how to fetch historical stock price data for any US ticker using Python and the Financial Datasets API. Includes daily, weekly, and monthly intervals. Historical stock price data is essential for backtesting trading strategies, building financial models, and rendering price charts. This guide walks you through fetching OHLCV (open, high, low, close, volume) price data using Python. ## Prerequisites * Python 3.7+ * A Financial Datasets API key ([sign up here](https://financialdatasets.ai)) * The `requests` library (`pip install requests`) ## Step 1: Set Up Authentication Every API request requires your API key in the `X-API-KEY` header. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ``` ## Step 2: Fetch Daily Stock Prices Use the [Prices API](/api/prices/historical) to pull end-of-day prices for any US ticker. You must specify a `ticker`, `interval`, `start_date`, and `end_date`. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ticker = "AAPL" interval = "day" # options: day, week, month, year start_date = "2024-01-01" end_date = "2024-12-31" url = ( f"https://api.financialdatasets.ai/prices/" f"?ticker={ticker}" f"&interval={interval}" f"&start_date={start_date}" f"&end_date={end_date}" ) response = requests.get(url, headers=headers) prices = response.json().get("prices") for price in prices[:5]: print(f"{price['time']}: Open={price['open']}, Close={price['close']}") ``` ## Step 3: Change the Interval Switch `interval` to get weekly, monthly, or yearly aggregated prices: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # Weekly prices interval = "week" # Monthly prices interval = "month" # Yearly prices interval = "year" ``` ## Step 4: Get a Real-Time Price Snapshot For the latest price, use the [Snapshot API](/api/prices/snapshot): ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = f"https://api.financialdatasets.ai/prices/snapshot?ticker=AAPL" response = requests.get(url, headers=headers) snapshot = response.json().get("snapshot") print(f"Price: ${snapshot['price']}") ``` ## Available Tickers You can fetch the full list of available tickers: ``` GET https://api.financialdatasets.ai/prices/tickers/ ``` This returns all 27,000+ tickers with historical price data from Databento, including 3 years of data. ## Next Steps * [Stock Prices API Reference](/api/prices/historical) — full parameter documentation * [Financial Statements Guide](/guides/analyze-financial-statements-python) — combine price data with fundamentals * [Quick Start](/quickstart) — overview of all available endpoints # How to Use Pagination Source: https://docs.financialdatasets.ai/guides/pagination How cursor pagination works across the Financial Datasets API: results arrive in pages, each response links the next one, and a simple loop fetches everything you asked for. List endpoints return results **in pages**. When your request matches more records than one page holds, the response includes a `next_page_url` — follow it to get the next page, and keep going until the field disappears. ## How it works Request income statements with `limit=25`: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25" \ -H "X-API-KEY: your_api_key_here" ``` The response contains the first page of statements plus a link to the next page: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "income_statements": [ /* one page of records */ ], "next_page_url": "https://api.financialdatasets.ai/financials/income-statements?cursor=eyJhbGciOi..." } ``` Request the `next_page_url` exactly as given — it is self-contained, no other parameters needed. The final page has **no** `next_page_url` field, which is your signal to stop. ## The loop ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = {"X-API-KEY": "your_api_key_here"} url = "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25" statements = [] while url: data = requests.get(url, headers=headers).json() statements.extend(data["income_statements"]) url = data.get("next_page_url") print(f"fetched {len(statements)} statements") ``` ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} const headers = { "X-API-KEY": "your_api_key_here" }; let url = "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25"; const statements = []; while (url) { const response = await fetch(url, { headers }); const data = await response.json(); statements.push(...data.income_statements); url = data.next_page_url; } console.log(`fetched ${statements.length} statements`); ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} URL="https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=25" while [ -n "$URL" ]; do RESP=$(curl -s "$URL" -H "X-API-KEY: your_api_key_here") echo "$RESP" | jq '.income_statements | length' URL=$(echo "$RESP" | jq -r '.next_page_url // empty') done ``` The same loop works on every list endpoint — only the array key changes (`prices`, `filings`, `insider_trades`, `news`, and so on). ## The cursor `next_page_url` carries an opaque `cursor` token that encodes your original request — its filters, and where the last page ended. * **Treat it as opaque.** Do not construct, modify, or store cursors long-term; get them from `next_page_url` only. * **Other parameters are ignored alongside a cursor.** The cursor already carries your original filters, so filters cannot change mid-walk. To change filters, start a new request without a cursor. * **Cursors are endpoint-specific.** A cursor from `/prices` will not work on `/filings`. A modified or foreign cursor returns `400`: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "error": "Invalid cursor", "message": "The cursor is invalid, was issued for a different endpoint, or was modified. Re-issue the original request without a cursor to start over." } ``` ## Page size Every page holds up to 10 records. Prices and the Treasury yield curve hold up to 100, sized for long histories of daily rows. ## What `limit` means `limit` is the **total** number of records you want; pagination just delivers it across as many pages as needed. A request small enough to fit in a single page returns no `next_page_url` at all. ## Billing Each page is a standard API request and is metered as one. ## Which endpoints paginate All endpoints that return a list of records: financial statements (including segments and as-reported), financial metrics, prices, filings, earnings, news, KPIs, insider trades, insider ownership, beneficial and activist ownership, institutional holdings, index funds, IPOs, the Treasury yield curve history, and inflation. Endpoints that return a single object — company facts, snapshots, interest rates — and `/filings/items` (the sections of one filing) always return their full result. # How to Search SEC Filings Source: https://docs.financialdatasets.ai/guides/search-sec-filings-python Learn how to search and retrieve SEC filings (10-K, 10-Q, 8-K) and extract specific sections like Risk Factors using Python. SEC filings contain the most authoritative information about public companies — from annual reports (10-K) to quarterly updates (10-Q) to material events (8-K). This guide shows you how to search filings and extract specific sections programmatically. ## Prerequisites * Python 3.7+ * A Financial Datasets API key ([sign up here](https://financialdatasets.ai)) * The `requests` library (`pip install requests`) ## Step 1: Set Up Authentication ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = { "X-API-KEY": "your_api_key_here" } ``` ## Step 2: Search Filings by Ticker Use the [Filings API](/api/filings/ticker) to find SEC filings for any US public company. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ticker = "AAPL" filing_type = "10-K" # options: 10-K, 10-Q, 8-K, and more limit = 5 url = ( f"https://api.financialdatasets.ai/filings" f"?ticker={ticker}" f"&type={filing_type}" f"&limit={limit}" ) response = requests.get(url, headers=headers) filings = response.json().get("filings") for filing in filings: print(f"{filing['filed_at']}: {filing['type']} - {filing['description']}") ``` ## Step 3: Extract Specific Filing Sections The real power is in extracting specific items from filings. Use the [Filing Items API](/api/filings/items) to pull individual sections without parsing the full document. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ticker = "AAPL" item = "1A" # Item 1A: Risk Factors filing_type = "10-K" url = ( f"https://api.financialdatasets.ai/filings/items" f"?ticker={ticker}" f"&item={item}" f"&type={filing_type}" f"&limit=1" ) response = requests.get(url, headers=headers) items = response.json().get("items") if items: print(f"Item 1A (Risk Factors):\n{items[0]['text'][:500]}...") ``` ## Common Filing Items Here are the most commonly requested sections from 10-K filings: | Item | Section | | ---- | ---------------------------------------------------------- | | 1 | Business Overview | | 1A | Risk Factors | | 7 | Management's Discussion and Analysis (MD\&A) | | 7A | Quantitative and Qualitative Disclosures About Market Risk | | 8 | Financial Statements and Supplementary Data | ## Step 4: Filter by Date Range Narrow your search to a specific time period: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/filings" f"?ticker=AAPL" f"&type=10-K" f"&filed_at_gte=2020-01-01" f"&filed_at_lte=2024-12-31" ) response = requests.get(url, headers=headers) filings = response.json().get("filings") ``` ## Step 5: Search by CIK Number If you have an SEC CIK number instead of a ticker, you can use that as well: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} cik = "0000320193" # Apple's CIK url = ( f"https://api.financialdatasets.ai/filings" f"?cik={cik}" f"&type=10-K" f"&limit=5" ) response = requests.get(url, headers=headers) filings = response.json().get("filings") ``` ## Next Steps * [Filings API Reference](/api/filings/ticker) — full parameter documentation * [Filing Items API Reference](/api/filings/items) — all available item types * [Financial Statements Guide](/guides/analyze-financial-statements-python) — get the structured numbers from these filings * [Company Facts API](/api/company/facts/ticker) — get company metadata and identifiers # How to Set Up Webhooks Source: https://docs.financialdatasets.ai/guides/setup-webhooks Receive real-time market events at your own endpoint. Step-by-step with a working Python receiver and signature verification. This guide walks you through receiving your first webhook delivery end-to-end: create a destination in the dashboard, spin up a receiver, verify the signature, and replay a delivery. By the end you'll have a production-ready handler. **Already integrated?** Jump to the [Webhooks reference](/webhooks) for the payload envelope, retry schedule, and production checklist, or the [event type catalog](/webhooks/events) for per-event payload schemas. ## Prerequisites * **Scale or Enterprise plan.** [Upgrade if needed](https://financialdatasets.ai/billing/subscriptions). * **Python 3.10+** for the code samples (Node alternative shown in tabs). * **An HTTPS endpoint you control.** For local testing, use a tunnel like [ngrok](https://ngrok.com) or [localtunnel](https://theboroer.github.io/localtunnel-www/) to expose `localhost`. ## What we'll build Throughout this guide we'll build a handler for a fictional integrator, **Acme Capital**. Acme wants a Slack ping the moment we publish new earnings for any ticker on their watchlist (`AAPL`, `MSFT`, `NVDA`). | | Value | | -------------------------------- | ------------------------------------------------------ | | **Acme's endpoint URL** | `https://acme.example.com/webhooks/financial-datasets` | | **Signing secret (placeholder)** | `whsec_PLACEHOLDER_FROM_DASHBOARD` | | **Event type** | `earnings.created` | | **Watchlist** | `AAPL`, `MSFT`, `NVDA` | Substitute your own values as you follow along. ## Step 1: Add a destination in the dashboard 1. Go to the [Webhooks](https://financialdatasets.ai/webhooks) page in your dashboard. 2. Click **Add destination**. 3. Paste your HTTPS endpoint URL — for Acme that's `https://acme.example.com/webhooks/financial-datasets`. 4. Expand the **Earnings** group, check `earnings.created`, click **Add destination**. 5. The new row appears with a truncated signing secret (`whsec_...`). Click the row to expand it, then click **Reveal** next to the signing secret and copy the full value. You'll plug it into the receiver in the next step. Treat your signing secret like a credential. Store it in a secret manager (not git, not your `.env` checked into source control), and rotate it from the dashboard if it ever leaks. ## Step 2: Spin up a receiver The receiver does three things: read the raw request body, verify the `FD-Signature` header, and return `2xx`. Install Flask: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} pip install flask ``` Save as `receiver.py`: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import hmac import hashlib import time from flask import Flask, request, abort app = Flask(__name__) # From the dashboard — Acme's destination signing secret. SIGNING_SECRET = "whsec_PLACEHOLDER_FROM_DASHBOARD" SIGNATURE_MAX_SKEW_SECONDS = 300 # Acme's earnings watchlist. Replace with your own. WATCHLIST = {"AAPL", "MSFT", "NVDA"} def verify(raw_body: bytes, header_value: str, secret: str) -> bool: try: parts = dict(p.split("=", 1) for p in header_value.split(",")) ts = int(parts["t"]) candidate = parts["v1"] except (KeyError, ValueError): return False if abs(int(time.time()) - ts) > SIGNATURE_MAX_SKEW_SECONDS: return False signing_input = f"{ts}.".encode("utf-8") + raw_body expected = hmac.new( secret.encode("utf-8"), signing_input, hashlib.sha256, ).hexdigest() return hmac.compare_digest(candidate, expected) def handle_earnings_created(event: dict) -> None: """Acme's business logic — ping Slack for watchlisted tickers.""" obj = event["data"]["object"] ticker = obj.get("ticker") if ticker in WATCHLIST: # Replace this with your Slack / pager / queue integration. print(f"🔔 watchlist hit: {ticker} reported earnings for " f"{obj.get('fiscal_period')}") else: print(f" skip {ticker} (not on watchlist)") @app.post("/webhooks/financial-datasets") def receive(): # IMPORTANT: read raw bytes BEFORE Flask parses to JSON. # The signature is computed over the exact bytes we sent. raw = request.get_data() sig = request.headers.get("FD-Signature", "") if not verify(raw, sig, SIGNING_SECRET): abort(400, "invalid signature") event = request.get_json() print(f"received {event['type']} id={event['id']} livemode={event['livemode']}") # TODO: in production, dedupe on event["id"] before doing side effects # and enqueue heavy work to a background job so this handler returns fast. if event["type"] == "earnings.created": handle_earnings_created(event) return "", 200 if __name__ == "__main__": app.run(port=5001) ``` Run it: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} python receiver.py ``` Then expose it via a tunnel for the dashboard to reach: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ngrok http 5001 # → copy the https://...ngrok-free.app URL into the destination's URL field ``` Install Express: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} npm install express ``` Save as `receiver.js`: ```js theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import crypto from 'node:crypto' import express from 'express' // From the dashboard — Acme's destination signing secret. const SIGNING_SECRET = 'whsec_PLACEHOLDER_FROM_DASHBOARD' const SIGNATURE_MAX_SKEW_SECONDS = 300 // Acme's earnings watchlist. Replace with your own. const WATCHLIST = new Set(['AAPL', 'MSFT', 'NVDA']) function verify(rawBody, headerValue, secret) { let ts, candidate try { const parts = Object.fromEntries( headerValue.split(',').map((p) => p.split('=', 2)), ) ts = parseInt(parts.t, 10) candidate = parts.v1 } catch { return false } if (Math.abs(Math.floor(Date.now() / 1000) - ts) > SIGNATURE_MAX_SKEW_SECONDS) { return false } const signingInput = Buffer.concat([ Buffer.from(`${ts}.`, 'utf8'), rawBody, ]) const expected = crypto .createHmac('sha256', secret) .update(signingInput) .digest('hex') const a = Buffer.from(candidate, 'hex') const b = Buffer.from(expected, 'hex') return a.length === b.length && crypto.timingSafeEqual(a, b) } // Acme's business logic — ping Slack for watchlisted tickers. function handleEarningsCreated(event) { const obj = event.data.object const ticker = obj.ticker if (WATCHLIST.has(ticker)) { // Replace this with your Slack / pager / queue integration. console.log( `🔔 watchlist hit: ${ticker} reported earnings for ${obj.fiscal_period}`, ) } else { console.log(` skip ${ticker} (not on watchlist)`) } } const app = express() // IMPORTANT: raw() must run BEFORE any JSON parser on this route, // so req.body is the exact bytes we sent. app.post( '/webhooks/financial-datasets', express.raw({ type: 'application/json' }), (req, res) => { const sig = req.header('FD-Signature') ?? '' if (!verify(req.body, sig, SIGNING_SECRET)) { return res.status(400).send('invalid signature') } const event = JSON.parse(req.body.toString('utf8')) console.log(`received ${event.type} id=${event.id} livemode=${event.livemode}`) // TODO: in production, dedupe on event.id before side effects // and enqueue heavy work to a background job so this handler returns fast. if (event.type === 'earnings.created') { handleEarningsCreated(event) } res.status(200).end() }, ) app.listen(5001, () => console.log('listening on :5001')) ``` Run + tunnel: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} node receiver.js ngrok http 5001 ``` ## Step 3: Fire a test event Back in the dashboard: 1. Find your destination row and click it to expand. 2. Click **Send test event**. 3. Within \~5 seconds your receiver should log two lines and the event should appear in **Recent events** with a green checkmark and HTTP `200`. Acme's receiver should log something like: ```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} received earnings.created id=b5fd9c10-e3b2-4c5d-a2b3-98fda43365cf livemode=False skip BLDR (not on watchlist) ``` The canned test event uses ticker `BLDR`, which isn't on Acme's watchlist — so it goes through the verify-and-skip branch. Once real `earnings.created` events for `AAPL`, `MSFT`, or `NVDA` arrive, the handler will hit the `🔔 watchlist hit` branch instead. Test events have `livemode: false` and use a canned payload matching your destination's event type (here, `earnings.created`) — useful for confirming the wiring before real data flows. Test events are throttled to **1 per minute per destination**. A second click within 60 seconds will return `429 Too Many Requests`. ## Step 4: Inspect a delivery Click any row in **Recent events** to slide up the detail drawer. You'll see: * **Request**: event type, event id, endpoint URL, attempt number, timestamps. * **Response**: HTTP status, duration, body returned by your endpoint. * **Signed payload**: the exact JSON we POSTed, ready to copy or download as `.json` for replaying in your local tests. If verification fails or your endpoint 5xx's, this drawer is where you'll diagnose it. The response body field will show whatever your server returned. ## Step 5: Replay a delivery From the detail drawer, click **Replay delivery**. We'll re-send the same event payload through the full delivery pipeline (signed with your *current* secret) and create a new row in **Recent events** with attempt number 1. The original row stays as a historical record. This is the fastest way to debug a handler fix — patch your code, deploy, hit Replay. ## Production checklist Before flipping real customers onto your handler: * **HTTPS endpoint.** Required in production; we reject `http://` URLs. * **Return 2xx within 10s.** Anything else counts as a failure. If real processing takes longer, enqueue to a background job and return `200` immediately. * **Dedupe on `event.id`.** Retries and replays mean the same id can arrive multiple times. A unique constraint on a `processed_events` table is the simplest reliable pattern. * **Watch the auto-disable threshold.** After 50 consecutive failed deliveries we automatically disable the destination to protect your endpoint. Catch issues earlier by monitoring the `Recent failures` field on the destination row. * **Rotate the signing secret if it leaks.** Click **Regenerate secret** from the destination's expanded row. The old secret stops working immediately, so deploy your config change in lockstep. ## Common pitfalls **Signature mismatch on every request.** You're hashing the JSON-parsed body instead of the raw bytes. Read the raw request body before any framework middleware parses it (see the `request.get_data()` / `express.raw()` calls in the samples above). **The 200 comes from your auth middleware, not your handler.** If a reverse proxy or auth layer swallows the request and replies with its own 200, our worker sees success but your handler never runs. Check your access logs. **Timeouts on big handlers.** Don't process the entire downstream pipeline inside the webhook handler. Enqueue and acknowledge. **Clock drift.** Our verification rejects timestamps more than 5 minutes off. If you keep failing right after a deploy, check NTP sync on your server. ## Next steps * [Webhook event types](/webhooks/events) — every event type, its payload schema, and the API endpoint its entries match. * [Secure your endpoint](/webhooks#verifying-the-signature) — signature verification in depth. * [Delivery behavior](/webhooks#delivery-behavior) — retries, ordering, and the auto-disable safety net. * [Production checklist](/webhooks#production-checklist) — work through this before going live. * Join the [Discord](https://discord.gg/hTtb8wzgSQ) if you hit something not covered here. # Introduction Source: https://docs.financialdatasets.ai/introduction Based in NYC, we build market infrastructure for agents. Financial Datasets lets you easily connect your agent to real-time, structured financial data - fundamentals, filings, ownership, earnings, KPIs, and more - using our clean, predictable APIs. New data hits the API within seconds of publication. We are a [primary-source provider](/data-provenance) of SEC data: statements, filings, and disclosures are collected, parsed, and served by us directly. Authenticate and make your first request in under two minutes. Give Claude, ChatGPT, Hermes, and other agents direct access to market data. Generate clients and wire tools from the machine-readable API spec. Get pushed the moment filings, earnings, or insider events hit. ## What You Can Access We cover **27,000+ active and delisted US tickers** with **30+ years** of history. Core datasets include: * **[Activist Ownership](/api/activist-ownership)** - Schedule 13D activist stakes, within a minute of hitting EDGAR. * **[Beneficial Ownership](/api/beneficial-ownership)** - Every 5%+ holder, activist and passive, from Schedules 13D and 13G. * **[Earnings Data](/api/earnings)** - Structured quarterly and annual results, estimates, and surprise flags. * **[Financial Statements](/api/financials/income-statements)** - Income statements, balance sheets, and cash flow statements. * **[Index Funds](/api/index-funds/ticker)** - ETF and index-fund holdings, weights, and which funds hold a security. * **[Insider Ownership](/api/insider-ownership)** - Form 3 and Form 5 ownership statements - what insiders actually hold. * **[Insider Trades](/api/insider-trades)** - Form 4 and Form 5 insider activity. * **[Institutional Holdings](/api/institutional-holdings/investor)** - SEC-direct Form 13F institutional holdings. * **[Macroeconomics](/api/macro/yield-curve/snapshot)** - Treasury yields, consumer price inflation, and central bank policy rates. * **[Operational KPIs](/api/kpi/metrics)** - KPI metrics, forward guidance, and non-GAAP metrics. * **[SEC Filings](/api/filings/ticker)** - 10-K, 10-Q, 8-K, and more - with access to specific sections (e.g. Item 1A, Item 7). * **[Segmented Financials](/api/financials/income-statement-segments)** - Business segment and geographic breakdowns. * **[Stock Prices](/api/prices/historical)** - Real-time and historical equity price data. ## Data Formats * **Structured** - clean, typed JSON with consistent field naming across every endpoint. * **Unstructured** - raw filing text and full documents, including section-level access to SEC filings. * **Normalized / standardized** - line items mapped to a consistent taxonomy so they're comparable across companies and time periods. * **As-reported** - figures exactly as the company filed them, preserving original labels and values without standardization. ## Built For * AI financial agents and LLM pipelines * Quantitative research platforms * Portfolio management systems * Event-driven trading infrastructure * Internal data layers for fintech products ## Design Principles * **Real-time ingestion** - filings are processed within seconds of publication. * **Structured JSON responses** - consistent field naming across all endpoints. * **Section-level filing access** - query specific sections of SEC filings without parsing full documents. * **Machine-first design** - optimized for programmatic consumption, not human browsing. Ready when you are — start with the [Quick Start](/quickstart). # Market Coverage Source: https://docs.financialdatasets.ai/market-coverage Complete US public company data for 27,000+ tickers over 30+ years. Financial Datasets provides **complete coverage of US publicly-traded companies** - both active and delisted - with over **27,000 tickers** and **30+ years** of historical data. This page outlines the scope of our coverage and how to discover available instruments. ## Coverage at a Glance * **100% of US public companies** - every company that files with the SEC is in our database. * **Active and delisted stocks** - survivorship-bias-free datasets for backtesting and historical analysis. * **30+ years of fundamentals** - income statements, balance sheets, and cash flow statements dating back to the early 1990s. * **27,000+ tickers** - spanning all sectors, market caps, and listing venues. ## Our Specialty Our core strengts are real-time earnings, fundamentals data, and operational KPIs. Our income statements, balance sheets, and cash flow statements are standardized across reporting periods and companies, giving you a clean, consistent dataset without the normalization burden that typically falls on your data engineering team. We also provide as-reported fundamentals as well. Every data point is linked backed to the source that it is derived from. ## Discovering Available Tickers To see which tickers are available for a given dataset, append `/tickers` to any endpoint: ``` GET https://api.financialdatasets.ai/financials/tickers/ ``` Visit the APIs section of this documentation for full endpoint references and query parameters. ## Current Limitations * **Non-US markets** are not yet available. * **Options, indices, and currencies** are not yet available. We are actively expanding coverage and plan to add international markets and additional instrument types. ## Feedback Have coverage requests or feedback? Contact us at [support@financialdatasets.ai](mailto:support@financialdatasets.ai). # MCP Server Source: https://docs.financialdatasets.ai/mcp-server Access the official MCP server for Financial Datasets. ## Overview Your AI assistant can use our official MCP server to access real-time financial data — stock prices, financials, SEC filings, news, and more. ## Connect your client Pick your client and follow the steps. Interactive clients sign you in automatically — no API key needed. Works for both **Claude.ai** (web) and the **Claude Desktop** app. 1. Go to **Settings** → **Connectors** 2. Click **Add** and enter the server URL: `https://mcp.financialdatasets.ai/` 3. Click **Add custom connector** and complete sign-in 4. In any new chat, click **+** and enable **Financial Datasets** under Connectors Run this in your terminal: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} claude mcp add --transport http financial-datasets https://mcp.financialdatasets.ai/ ``` Then type `/mcp` inside Claude Code and complete sign-in in your browser. Verify anytime with `claude mcp list`. Install the official **Financial Datasets** plugin from ChatGPT's Plugin Directory. 1. Open [Financial Datasets in ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_69cacd9394a88191ba6564e1bb0430fa), or search for **Financial Datasets** in the Plugin Directory 2. Click **Install plugin**, connect the Financial Datasets app, and complete sign-in 3. In a new chat, mention `@Financial Datasets` or select it from **+** → **More** Run these commands in your terminal: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} codex mcp add financial-datasets --url https://mcp.financialdatasets.ai/ codex mcp login financial-datasets ``` Complete sign-in in your browser. The server is then available in the Codex app, CLI, and IDE extension. Verify anytime with `codex mcp list` or type `/mcp` in Codex. Add the server to `~/.hermes/config.yaml`: ```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} mcp_servers: financial-datasets: url: "https://mcp.financialdatasets.ai/" auth: oauth ``` Then run OAuth sign-in from a fresh terminal (don't start it from inside an already-running Hermes session — the auto-reload timeout is too short for browser auth): ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} hermes mcp login financial-datasets ``` Complete sign-in in your browser. In an active Hermes session, reload MCP tools with `/reload-mcp`, or start a new chat: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} hermes chat ``` See Hermes' [MCP docs](https://hermes-agent.nousresearch.com/docs/user-guide/features/mcp) for filtering, re-auth, and troubleshooting. Add the Financial Datasets MCP server to OpenClaw, then complete OAuth sign-in: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} openclaw mcp add financial-datasets \ --url https://mcp.financialdatasets.ai/ \ --transport streamable-http \ --auth oauth openclaw mcp login financial-datasets ``` OpenClaw prints an authorization URL — approve in your browser, then finish with: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} openclaw mcp login financial-datasets --code ``` Verify the connection anytime with: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} openclaw mcp probe financial-datasets ``` Prefer editing config by hand? Add this under `mcp.servers` in `~/.openclaw/openclaw.json`, then run the same `openclaw mcp login` flow: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "mcp": { "servers": { "financial-datasets": { "url": "https://mcp.financialdatasets.ai/", "transport": "streamable-http", "auth": "oauth" } } } } ``` See OpenClaw's [MCP docs](https://docs.openclaw.ai/cli/mcp) for full CLI and config reference. Add the following to your `~/.cursor/mcp.json` file, then save and restart Cursor: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "mcpServers": { "financial-datasets": { "url": "https://mcp.financialdatasets.ai/" } } } ``` Cursor automatically detects all available tools and calls the relevant one when you ask financial data questions in chat. ## Programmatic access Building a script or a production agent? Connect to the `https://mcp.financialdatasets.ai/api` endpoint with an API key ([sign up free](https://financialdatasets.ai/register), then generate a key in your [dashboard](https://financialdatasets.ai/)). For scripts, notebooks, and custom MCP integrations, connect to the `/api` endpoint with your API key. Install the MCP Python SDK: ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} pip install mcp ``` Connect, then call a tool — here we fetch the latest price for Apple: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import asyncio from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client API_KEY = "your-api-key" SERVER_URL = "https://mcp.financialdatasets.ai/api" async def main(): # Open an authenticated connection to the MCP server async with streamablehttp_client( SERVER_URL, headers={"X-API-KEY": API_KEY}, ) as streams: read_stream, write_stream, _ = streams # Start an MCP session async with ClientSession(read_stream, write_stream) as session: await session.initialize() # Call any tool from the MCP Tools list result = await session.call_tool( "get_stock_price", {"ticker": "AAPL"}, ) print(result.content) asyncio.run(main()) ``` For production agents built on Anthropic's hosted Managed Agents platform, authenticate with your API key using a `static_bearer` vault credential. 1. Generate an API key from your [account dashboard](https://financialdatasets.ai). 2. Create a `static_bearer` vault credential pointing at our `/api` endpoint: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "type": "static_bearer", "mcp_server_url": "https://mcp.financialdatasets.ai/api", "token": "your-api-key" } ``` 3. Reference the vault ID when creating a session. Anthropic injects `Authorization: Bearer ` on every MCP call. See Anthropic's [vault credentials docs](https://platform.claude.com/docs/en/managed-agents/vaults) for full SDK examples in Python, TypeScript, Go, and Java. ## Available tools **Beneficial Ownership** * **`get_beneficial_owners`**: List beneficial owners (holders of more than 5% of a company's shares, from SEC Schedules 13D/13G) with their filer CIK and name. Optionally filter by name prefix. Use this to discover the `filer_cik` to pass to `get_beneficial_ownership`. * **`get_beneficial_ownership`**: Get 5%+ beneficial-ownership stakes from SEC Schedules 13D and 13G. Query by `ticker` (who owns this company) or by `filer_cik` (what stakes does this owner hold). Use `type=activist` for Schedule 13D activist stakes or `type=passive` for 13G stakes; `history=true` returns each stake's full amendment chain instead of its current state. **Company Information** * **`get_company_facts`**: Get company details including employee count, sector, industry, exchange, and more. **Earnings** * **`get_earnings`**: Get earnings data from SEC filings. Both modes return a flat list of `EarningsRecord` entries — same shape in either mode. With `ticker`, returns the most recent SEC filings (8-K / 10-Q / 10-K / 20-F) for that company. Without `ticker`, returns the most recently filed earnings across all covered companies (the real-time feed). Each entry exposes `report_period`, `source_type`, `filing_date`, `accession_number`, plus `quarterly` and/or `annual` financial blocks. **Financial Metrics** * **`get_financial_metrics`**: Get historical financial metrics such as P/E ratio, enterprise value, and revenue per share. * **`get_financial_metrics_snapshot`**: Get a snapshot of the latest financial metrics, including market cap, P/E ratio, and dividend yield. **Financial Statements** * **`get_income_statement`**: Get historical income statement data (revenue, expenses, net income). * **`get_balance_sheet`**: Get historical balance sheet data (assets, liabilities, equity). * **`get_cash_flow_statement`**: Get historical cash flow statement data (operating, investing, financing activities). Each of these tools accepts an `as_reported` flag. Set `as_reported: true` to return the raw line items exactly as they appear in the company's filing, instead of our standardized fields. As-reported data supports only `annual` and `quarterly` periods (a `ttm` period is treated as `annual`). **Index Funds** * **`get_index_fund`**: Get an ETF or index fund's holdings and each position's weight (percent of net assets) for a fund ticker (e.g., SPY). Returns the fund's latest filing by default, or the composition as of a past date via `as_of`; optionally filter by `asset_class`. **Insider Ownership** * **`get_insider_ownership`**: Get insider ownership statements for a company: what officers, directors, and 10% owners actually hold (common shares, options, RSUs), from SEC Forms 3 and 5. Complements `get_insider_trades` — trades are the events, ownership statements are the state. Filter by insider `name` or `form_type` (`3` for initial statements, `5` for annual statements). **Insider Trades** * **`get_insider_trades`**: Get insider trading transactions for a company, including purchases, sales, and other transactions by officers, directors, and major shareholders. **Institutional Holdings** * **`get_institutional_investors`**: List institutional investors (SEC 13F filers) with their CIK and most recent reported name. Optionally filter by case-insensitive name prefix to discover the `filer_cik` to pass to `get_institutional_holdings`. * **`get_institutional_holdings`**: Get SEC 13F institutional holdings sourced directly from EDGAR. Query by `filer_cik` (what positions a filer holds) or by `ticker` (which institutional filers hold this security). Defaults to the latest available quarter; optional `report_period`, `report_period_gte`, and `report_period_lte` filters narrow the range. **Interest Rates** * **`get_interest_rates`**: Get the latest policy interest rates from major central banks (e.g., FED, ECB, BOE, BOJ). Returns a snapshot of each bank's current rate — no parameters required. **Key Performance Indicators** * **`get_kpi_guidance`**: Get forward-looking KPI guidance items issued by management in earnings releases and filings. Filter by ticker, period, metric name, and date range. * **`get_kpi_metrics`**: Get historical KPI taxonomy metrics extracted from SEC filings (e.g., subscriber counts, ARPU, units sold). Filter by ticker, period (quarterly/annual), metric name, and date range. * **`get_kpi_non_gaap`**: Get non-GAAP KPIs reported by companies (e.g., Adjusted EBITDA, Free Cash Flow as defined by the company). Filter by ticker, period, metric name, and date range. KPI data is available on all paid plans. **News** * **`get_news`**: Get recent news articles for a specific company or the broad market. Pass a ticker for company-specific news, or omit the ticker for general market news. **SEC Filings** * **`get_filings`**: Get a list of historical SEC filings for a company (10-K, 10-Q, 8-K, and more). * **`get_filing_items`**: Extract specific sections from 10-K, 10-Q, and 8-K filings (e.g., Risk Factors, MD\&A). * **`list_filing_item_types`**: Get a list of all extractable items for 10-K, 10-Q, and 8-K filings. **Segmented Financials** * **`get_segmented_financials`**: Get segment breakdowns from all three financial statement types (income statement, balance sheet, cash flow) in a single call. Returns revenue, operating income, and depreciation by product/segment; assets, goodwill, and long-lived assets by segment; and capital expenditure by segment. **Stock Prices** * **`get_stock_prices`**: Get historical stock price data (open, high, low, close, volume) over a date range with configurable intervals. * **`get_stock_price`**: Get the latest price snapshot for a stock, including current price and OHLCV data. **Stock Screener** * **`screen_stocks`**: Screen and filter stocks by financial metrics, valuation ratios, and company attributes. Combine multiple conditions to find stocks matching your criteria (e.g., revenue > \$1B, P/E \< 20, sector = "Technology"). * **`list_stock_screener_filters`**: Get a list of all available filter fields and operators for the stock screener, grouped by category. ## Example prompts After connecting, try asking your AI assistant questions like: * "What is Apple's current P/E ratio and market cap?" * "Show me Tesla's income statement for the last 4 quarters" * "Screen for technology stocks with a P/E under 20 and revenue over \$1 billion" * "Find the Risk Factors section from Microsoft's latest 10-K" * "Are there any activist investors in BlackBerry?" * "What companies just reported earnings today?" # OpenAPI Spec Source: https://docs.financialdatasets.ai/openapi-spec Machine-readable API specification for programmatic integration The full OpenAPI 3.0.1 specification for the Financial Datasets API is publicly available: [https://financialdatasets.ai/openapi.json](https://financialdatasets.ai/openapi.json) ## What's included The spec covers all 27 API endpoints with complete request/response schemas, authentication details, and parameter descriptions. You can use it to: * **Generate client libraries** in any language using tools like [openapi-generator](https://openapi-generator.tech/) * **Import into API clients** like Postman, Insomnia, or Bruno * **Power AI agents** that need to discover and call endpoints programmatically * **Validate requests and responses** against the official schema # Quick Start Source: https://docs.financialdatasets.ai/quickstart Get started with the Financial Datasets API in under 2 minutes. Install, authenticate, and make your first stock data API call. ## 1. Create an account Sign up at [financialdatasets.ai](https://financialdatasets.ai) and generate your **API key** from the dashboard. ## 2. Make your first request Every request needs two things: * Your API key in the `X-API-KEY` header * A `ticker` query parameter ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests headers = {"X-API-KEY": "your_api_key_here"} url = "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=4" response = requests.get(url, headers=headers) data = response.json() for stmt in data["income_statements"]: print(f"{stmt['report_period']}: Revenue = ${stmt['revenue']:,.0f}") ``` ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} const response = await fetch( "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=4", { headers: { "X-API-KEY": "your_api_key_here" } } ); const data = await response.json(); data.income_statements.forEach((stmt) => { console.log(`${stmt.report_period}: Revenue = $${stmt.revenue.toLocaleString()}`); }); ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl "https://api.financialdatasets.ai/financials/income-statements?ticker=AAPL&period=annual&limit=4" \ -H "X-API-KEY: your_api_key_here" ``` ## 3. Explore more endpoints Now that you have the basics, try a few more calls: ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # authenticate headers = {"X-API-KEY": "your_api_key_here"} # get the real-time price snapshot for NVDA url = "https://api.financialdatasets.ai/prices/snapshot?ticker=NVDA" response = requests.get(url, headers=headers) # parse the snapshot from the response snapshot = response.json()["snapshot"] print(f"NVDA: ${snapshot['close']}") ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # authenticate headers = {"X-API-KEY": "your_api_key_here"} # get company facts for Tesla url = "https://api.financialdatasets.ai/company/facts?ticker=TSLA" response = requests.get(url, headers=headers) # parse company facts from the response facts = response.json()["company_facts"] print(f"{facts['name']} — {facts['sector']}, {facts['industry']}") ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # authenticate headers = {"X-API-KEY": "your_api_key_here"} # get the 5 most recent insider trades for Apple url = "https://api.financialdatasets.ai/insider-trades?ticker=AAPL&limit=5" response = requests.get(url, headers=headers) # parse insider trades from the response trades = response.json()["insider_trades"] for t in trades: print(f"{t['name']}: {t['transaction_shares']} shares on {t['transaction_date']}") ``` ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests # authenticate headers = {"X-API-KEY": "your_api_key_here"} # use the screener to find companies with revenue > $50B url = "https://api.financialdatasets.ai/financials/search/screener" body = { "filters": [ {"field": "revenue", "operator": "gt", "value": 50000000000} ], "limit": 10 } response = requests.post(url, json=body, headers=headers) # parse the results from the response results = response.json()["results"] for r in results: print(f"{r['ticker']}: Revenue = ${r['revenue']:,.0f}") ``` ## 4. What's next? Income statements, balance sheets, and cash flow statements. Historical and real-time price data. 10-K, 10-Q, 8-K filings with section-level extraction. Connect your AI assistant directly to our data. # Webhooks Source: https://docs.financialdatasets.ai/webhooks Push notifications for real-time market events. Scale and Enterprise. ## Overview Instead of polling our API for new data, you can register an HTTPS endpoint and we'll POST to it the moment an event fires. Use webhooks to wake up an agent on a fresh earnings release, new financial statements, extracted KPIs and guidance, insider filings, or a new macro print; push records into your warehouse; or trigger downstream automation. **New to webhooks?** The [setup guide](/guides/setup-webhooks) walks you through a working Python receiver end-to-end in under 15 minutes. This page is the reference you'll come back to once you're integrated. Webhooks are available on **Scale** and **Enterprise** plans. [Manage your plan](https://financialdatasets.ai/billing/subscriptions) from the dashboard. ## Get started Five steps to get from zero to receiving events: Register an HTTPS endpoint and the events you want to receive from the [Webhooks dashboard](https://financialdatasets.ai/webhooks). Stand up an HTTPS handler that can accept JSON POSTs and read the raw request body. See the [setup guide](/guides/setup-webhooks) for Python + Node examples. Confirm each request came from us using the `FD-Signature` header. See [Verifying the signature](#verifying-the-signature). Fire a test event from the dashboard's destination row and confirm your endpoint returns `2xx` within 10 seconds. Walk through the [production checklist](#production-checklist) before flipping real customer flows onto your handler. ## Production checklist Before relying on webhooks for production-critical flows, work through each of these: 1. **Use HTTPS, not HTTP.** Your endpoint URL must start with `https://`. We won't deliver to plain `http://` in production. [Security →](#security) 2. **Confirm each request actually came from us.** Use the `FD-Signature` header to check authenticity. Skip this and anyone could forge events. [How to verify →](#verifying-the-signature) 3. **Reply within 10 seconds.** Send back `200 OK` quickly, then do the heavy work in the background. Slow replies count as failures and we'll retry. [Delivery behavior →](#delivery-behavior) 4. **Return `2xx` for event types you don't handle.** A handler that throws on an unrecognized type turns our delivery into a failure. Acknowledge first, then decide what to process. [Troubleshooting →](#troubleshooting) 5. **Don't process the same event twice.** We may deliver the same event more than once. Track which `event.id` values you've handled and skip duplicates. [Idempotency →](#idempotency) 6. **Keep your signing secret safe.** Treat it like a password: never commit it to git, store it in a secret manager, and rotate it from the dashboard if it ever leaks. [Security →](#security) ## Event types We publish 16 event types across seven families. A destination can subscribe to any combination. | Family | Events | When they arrive | | ------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | | **Earnings** | `earnings.created` | Within minutes of the filing hitting EDGAR. | | **Financial statements** | `income_statements.created`, `balance_sheets.created`, `cash_flow_statements.created`, `financial_metrics.created` | Within minutes of a 10-K, 10-Q, 20-F, or 6-K being processed. | | **Segmented financials** | `income_statement_segments.created`, `balance_sheet_segments.created`, `cash_flow_statement_segments.created` | Same filings, only when the filing reports segment breakdowns. | | **Earnings intelligence** | `operating_kpis.created`, `forward_guidance.created`, `non_gaap_metrics.created` | Minutes after `earnings.created`, once analysis completes. | | **Insider activity** | `insider_trades.created`, `insider_ownership.created` | Once daily, early morning UTC, covering the previous day's filings. | | **Filings** | `filing_items.metadata.created` | Within minutes of a 10-K, 10-Q, or 8-K being processed. Metadata only, with a url to fetch the filing text. | | **Macroeconomics** | `yield_curve.created`, `inflation.created` | The evening a new Treasury yield curve day is published; within hours of each monthly consumer price release. | Full catalog: the payload each event carries, its field schema, and the API endpoint its entries match. ## Payload format Every delivery is a `POST` of a JSON envelope wrapping a resource. The envelope is identical across event types; `data.object` carries the resource, and its shape depends on the event `type`. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "04b97437-62cd-4ccb-b7eb-54765dbaa72d", "type": "earnings.created", "api_version": "2026-05-20", "livemode": true, "created": 1779309269, "data": { "object": { "...": "shape depends on type" } } } ``` Array entries inside `data.object` are identical to entries from the corresponding API response, so any parser you've written against our REST endpoints works unchanged. See [Webhook event types](/webhooks/events) for the per-event schema. ## Headers Every request includes: | Header | Value | | -------------- | ---------------------------------- | | `Content-Type` | `application/json` | | `User-Agent` | `FinancialDatasets-Webhook/1.0` | | `FD-Signature` | `t=,v1=` | ## Verifying the signature The `FD-Signature` header lets you confirm the request actually came from us and wasn't tampered with. The signature is an HMAC-SHA256 of `{timestamp}.{raw_body}` using your destination's signing secret. Always verify against the **raw request bytes**. If you parse the body to JSON and re-serialize before hashing, the bytes won't match and verification will fail. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import hmac import hashlib import time SIGNATURE_MAX_SKEW_SECONDS = 300 # 5 minutes def verify(raw_body: bytes, header_value: str, secret: str) -> bool: try: parts = dict(piece.split("=", 1) for piece in header_value.split(",")) ts = int(parts["t"]) candidate = parts["v1"] except (KeyError, ValueError): return False # Reject anything outside the skew window — defeats replay attacks # if your signing secret ever leaks. if abs(int(time.time()) - ts) > SIGNATURE_MAX_SKEW_SECONDS: return False signing_input = f"{ts}.".encode("utf-8") + raw_body expected = hmac.new( secret.encode("utf-8"), signing_input, hashlib.sha256, ).hexdigest() return hmac.compare_digest(candidate, expected) ``` ```js theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import crypto from 'node:crypto' const SIGNATURE_MAX_SKEW_SECONDS = 300 // 5 minutes export function verify(rawBody, headerValue, secret) { let ts, candidate try { const parts = Object.fromEntries( headerValue.split(',').map((p) => p.split('=', 2)), ) ts = parseInt(parts.t, 10) candidate = parts.v1 } catch { return false } if (Math.abs(Math.floor(Date.now() / 1000) - ts) > SIGNATURE_MAX_SKEW_SECONDS) { return false } const signingInput = Buffer.concat([ Buffer.from(`${ts}.`, 'utf8'), Buffer.isBuffer(rawBody) ? rawBody : Buffer.from(rawBody, 'utf8'), ]) const expected = crypto .createHmac('sha256', secret) .update(signingInput) .digest('hex') // Lengths must match before timingSafeEqual; otherwise it throws. const a = Buffer.from(candidate, 'hex') const b = Buffer.from(expected, 'hex') return a.length === b.length && crypto.timingSafeEqual(a, b) } ``` Use a constant-time comparison (`hmac.compare_digest` / `crypto.timingSafeEqual`). A normal `==` is vulnerable to timing attacks. ## Delivery behavior A delivery succeeds when your endpoint returns any `2xx` response within 10 seconds. Anything else — a `4xx`, a `5xx`, a connection error, or a timeout — counts as a failure, and we'll retry on this schedule: | Attempt | When we try it | | ------- | -------------------------------------------------- | | 1 | Immediately, as soon as the event fires. | | 2 | About 1 minute after attempt 1 (±10s of jitter). | | 3 | About 10 minutes after attempt 2 (±60s of jitter). | After three failed attempts we stop trying that specific event. The destination stays active and keeps receiving new events normally; you'll just see this delivery marked `Dead` in the dashboard. **Ordering is not guaranteed.** Events for the same resource can interleave, and a retry that succeeds late can land after a newer event. Don't build logic that assumes arrival order. **Auto-disable safety net.** If a destination piles up **50 consecutive failed deliveries**, we automatically disable it so we don't keep pounding on a broken endpoint. You'll see `Auto-disabled` on the row with a short reason. Once you've fixed the issue, re-enable it from the row's expanded view. We email the account owner along the way: a heads-up at **25 consecutive failures**, and again if the destination is disabled at 50. A single successful delivery resets the counter and re-arms the warning. ### Idempotency The same `event.id` can arrive more than once: replays, retries that succeed late, network races. Your handler must be idempotent. * Dedupe on `id` (e.g. insert into a `processed_events` table with a unique constraint and ignore conflicts). * Don't trust delivery order; events for the same resource can interleave. ## Test mode The **Send test event** button on each destination row fires a canned event with `livemode: false`, shaped exactly like a real event: an earnings destination gets an `earnings.created` test, an insider destination gets an insider-shaped test. If your handler parses the test event, it parses real events. A destination subscribed to several event types gets a test of the first type it subscribes to. To exercise a specific one, replay a real delivery of that type from **Recent events** instead. Test events are delivered only to the destination you fired them from, and are throttled to **1 per minute per destination**. ## Security * **HTTPS only.** We refuse to deliver to plain `http://` URLs in production. * **SSRF defense.** We resolve your URL's IP at every delivery attempt and reject private (RFC 1918), loopback, link-local, and metadata-service ranges. * **Signing-secret rotation.** Use **Regenerate secret** on the destination's row whenever you suspect a leak. The old secret stops working as soon as you rotate, so deploy the new secret to your handler in lockstep. * **Secret access.** Re-copy your secret from the destination's row in the dashboard if you misplace it. Retrieval is gated by your dashboard login; API keys cannot read signing secrets. ## Limits | Limit | Value | | ---------------------------------------- | ----------------------------------------------------- | | Active destinations per account | 5. Disable or delete unused ones to free up slots. | | Event types per destination | Any combination; one endpoint can receive everything. | | Delivery attempts per event | 3, then the delivery is marked `Dead`. | | Response deadline | 10 seconds. | | Consecutive failures before auto-disable | 50 (warning email at 25). | | Test events | 1 per minute per destination. | | Signature skew window | 5 minutes. | ## Troubleshooting **Destination keeps auto-disabling.** Open the destination's expanded row and check `Recent failures`. Your endpoint is probably 5xx-ing or timing out beyond 10s. The fastest debug path is replaying a recent failed delivery from **Recent events** and inspecting the response body that came back. **Some event types fail while others succeed.** Open **Recent events** and compare the `Event` and `Response` columns: if one family of events fails while the rest deliver fine, the problem is in your handler's branch for those types, not the connection. Your server logs will have the stack trace, and replaying one of the failed deliveries from **Recent events** reproduces the exact payload on demand. A destination in this state never auto-disables, because the successful deliveries keep resetting the consecutive-failure counter, so it can stay half-broken indefinitely. If you don't need those event types, edit the destination and unsubscribe from them. **Signature verification fails.** Three usual suspects: 1. You parsed the body before computing the HMAC. Always verify the raw bytes. 2. The signing secret in your config is stale after a rotation. Re-copy from the dashboard. 3. Your server has clock drift > 5 minutes. We reject signatures outside the skew window. **No events arrive at all.** Confirm the destination is `Active` (not Disabled). Fire a test event from the row's **⋯** menu; if that doesn't arrive within \~5 seconds, the destination URL is unreachable from our network (check firewalls / IP allowlists). Still stuck? Open a ticket via [Support](/support) and include the destination id + a recent event id from the dashboard. ## See also * [Webhook event types](/webhooks/events) — the full catalog with payload schemas. * [How to set up webhooks](/guides/setup-webhooks) — step-by-step walkthrough with a working Python receiver. * [Open the Webhooks dashboard](https://financialdatasets.ai/webhooks) to create your first destination. # Webhook Event Types Source: https://docs.financialdatasets.ai/webhooks/events Every event type you can subscribe to, the payload each one carries, and the API endpoint its entries match. This is the complete catalog of event types. Each entry names the payload shape it carries and the API endpoint its entries match, so you can reuse parsers you have already written. For how delivery, retries, and signature verification work, see the [Webhooks reference](/webhooks). ## Envelope Every delivery is a `POST` of the same JSON envelope. Only `data.object` varies by event type. | Field | Type | Description | | ------------- | ------------- | ------------------------------------------------------------------------ | | `id` | string (UUID) | The event id. Use this for idempotency / deduplication. | | `type` | string | The event type, e.g. `earnings.created`. | | `api_version` | string | The API version pinned on your destination (date-stamped). | | `livemode` | boolean | `false` for test events fired from the dashboard, `true` for production. | | `created` | integer | Unix timestamp (seconds) of when we recorded the event. | | `data.object` | object | The resource payload. Shape depends on `type`. | ## Payload shapes Four shapes cover every event type that carries data, and each catalog entry below names which one it uses. `filing_items.metadata.created` is the exception: it carries filing metadata rather than data, and its shape is documented with the event itself. ### Filing-level Used by the four statement events, the three segment events, and the two insider events. A header identifying the filing, plus an array named after the event's dataset. | Field | Type | Description | | ------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `ticker` | string | Ticker of the company that filed. | | `accession_number` | string | The SEC's unique id for this filing. | | `filing_date` | string (date) \| null | Date the filing was filed with the SEC. | | `form_type` | string | The form as filed, so amendments keep their suffix: `10-K`, `10-Q`, `20-F`, `6-K`, `4`, `3`, or an amendment such as `10-Q/A`. | | *dataset key* | array | The dataset's entries for this filing. The key matches the event type: an `income_statements.created` event carries `income_statements`. | Each array entry is identical to a single entry from the corresponding API response. **Header vs. entry `form_type`.** Statement entries carry their own `form_type` recording which form that row came from. It matches the header for the filing's reported period, and is `null` on `ttm` entries, because a trailing twelve month window can span multiple filings. Read the header when you want the filing; read the entry when you want that row's provenance. Segment entries carry no `form_type`, `filing_date`, or `filing_datetime`. ### Release-level Used by the three earnings intelligence events. Keyed to an earnings release rather than a filing period. | Field | Type | Description | | ------------------ | --------------------- | ----------------------------------------------------------------------- | | `ticker` | string | Ticker of the company that reported. | | `accession_number` | string | The SEC's unique id for the earnings release filing. | | `sector` | string | The sector whose KPI definitions we applied. | | `report_period` | string (date) \| null | The fiscal period the release covers. | | *dataset key* | array | The dataset's entries for this release. The key matches the event type. | ### Earnings Used only by `earnings.created`. The `data.object` is a single entry from the [`GET /earnings/`](/api/earnings) response, with no wrapper array. ### Print-level Used by the two macro events. A `date` header naming the print, plus the same body the dataset's snapshot endpoint returns, under the same key. | Field | Type | Description | | ------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `date` | string (date) | The print's date: the business day for the yield curve, the first day of the reference month for inflation. | | *dataset key* | object \| array | Identical to the body of the corresponding snapshot response: `yield_curve` is one object, `inflation` is an array with one entry per series. | One event per dataset per new date. A later revision of an already published date does not fire a new event; the snapshot and history endpoints serve the revised values. ## Event types Listed alphabetically. ### `balance_sheets.created` Fires when a filing's balance sheets are extracted, within minutes of a 10-K, 10-Q, 20-F, or 6-K being processed. Shape: [filing-level](#filing-level), carrying `balance_sheets`. Entries match [`GET /financials/balance-sheets`](/api/financials/balance-sheets). ### `balance_sheet_segments.created` Fires when a filing reports balance sheet segment breakdowns. Balance sheet segments are rarer than income statement segments, so expect this event for fewer filings. Shape: [filing-level](#filing-level), carrying `balance_sheet_segments`. Entries match [`GET /financials/balance-sheets/segments`](/api/financials/balance-sheet-segments). ### `cash_flow_statements.created` Fires when a filing's cash flow statements are extracted, within minutes of a 10-K, 10-Q, 20-F, or 6-K being processed. Shape: [filing-level](#filing-level), carrying `cash_flow_statements`. Entries match [`GET /financials/cash-flow-statements`](/api/financials/cash-flow-statements). ### `cash_flow_statement_segments.created` Fires when a filing reports cash flow statement segment breakdowns. Like balance sheet segments, these are reported by fewer filings. Shape: [filing-level](#filing-level), carrying `cash_flow_statement_segments`. Entries match [`GET /financials/cash-flow-statements/segments`](/api/financials/cash-flow-statement-segments). ### `earnings.created` Fires when we parse a new earnings release (8-K) or quarterly/annual report, within minutes of the filing hitting EDGAR. Shape: [earnings](#earnings). The `data.object` is a single [`GET /earnings/`](/api/earnings) entry, so any parser written against the Earnings API works unchanged. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "04b97437-62cd-4ccb-b7eb-54765dbaa72d", "type": "earnings.created", "api_version": "2026-05-20", "livemode": true, "created": 1779309269, "data": { "object": { "ticker": "NDSN", "report_period": "2026-04-30", "fiscal_period": "2026-Q2", "currency": "USD", "source_type": "8-K", "filing_date": "2026-05-20", "filing_datetime": "2026-05-20T16:33:44-04:00", "filing_url": "https://www.sec.gov/Archives/edgar/data/72331/000007233126000022/0000072331-26-000022-index.htm", "accession_number": "0000072331-26-000022", "quarterly": { "revenue": 740847000, "net_income": 117316000, "earnings_per_share": 2.10, "...": "see Earnings API reference" } } } } ``` **A single quarter can fire more than one `earnings.created` event.** The 8-K earnings release fires first, then the 10-Q (or 10-K for the fiscal-year quarter) follows 30 to 45 days later with the full GAAP-audited numbers. Both carry the same `(ticker, report_period)` but different `accession_number`s and different `source_type`s. See [Handling multiple earnings events](#handling-multiple-earnings-events) below. ### `filing_items.metadata.created` Fires when a filing's items become available, which is the moment [`GET /filings/items`](/api/filings/items) can serve them quickly. Covers 10-K, 10-Q, and 8-K filings and their amendments (`10-K/A`, `10-Q/A`, `8-K/A`), one event per filing. **This event carries metadata, not filing text.** Filing text runs to megabytes, which would blow the 10 second delivery deadline, so the payload gives you the filing header, the items it contains, and a `url` to fetch the text from. Treat it as a notification to go pull, not as the data itself. | Field | Type | Description | | ------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------- | | `ticker` | string | Ticker of the company that filed. | | `cik` | string | The company's 10-digit zero-padded SEC CIK. | | `accession_number` | string | The SEC's unique id for this filing. | | `filing_type` | string | The form as filed, so amendments keep their suffix: `10-K`, `10-Q`, `8-K`, `10-K/A`, `10-Q/A`, or `8-K/A`. | | `filing_date` | string (date) \| null | Date the filing was filed with the SEC. | | `available_items` | array of string | The items this filing actually contains, in the exact form the `item` query parameter accepts. | | `url` | string | Ready-to-call `GET /filings/items` URL for the full payload. | ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "b3f1c2d4-5e6a-47b8-9c0d-1e2f3a4b5c6d", "type": "filing_items.metadata.created", "api_version": "2026-05-20", "livemode": true, "created": 1783291200, "data": { "object": { "ticker": "AAPL", "cik": "0000320193", "accession_number": "0000320193-26-000002", "filing_type": "8-K", "filing_date": "2026-02-19", "available_items": ["Item-2.02", "Item-9.01"], "url": "https://api.financialdatasets.ai/filings/items/?ticker=AAPL&filing_type=8-K&accession_number=0000320193-26-000002" } } } ``` **Using `available_items`.** The values are exactly what the `item` query parameter accepts, so you can filter before spending a call. Append `&item=` to the `url` to fetch a single section: ``` https://api.financialdatasets.ai/filings/items/?ticker=AAPL&filing_type=8-K&accession_number=0000320193-26-000002&item=Item-2.02 ``` Item naming follows the filing family: 10-K items look like `Item-1A`, 10-Q items are part-qualified as `Part-1,Item-2`, and 8-K items carry their decimal number as `Item-2.02`. A filing contains any subset, so check `available_items` rather than assuming a given item is present. This makes the event a cheap filter: an agent that only cares about earnings releases can watch for `Item-2.02` and ignore every other 8-K without fetching anything. Fetching the `url` is a normal billed API call, and it hits a warm cache. See [`GET /filings/items`](/api/filings/items) for the response schema and the full list of item names. ### `financial_metrics.created` Fires when a filing's financial metrics (valuation, margins, ratios, growth) are computed. Shape: [filing-level](#filing-level), carrying `financial_metrics`. Entries match [`GET /financial-metrics`](/api/financial-metrics/historical). ### `forward_guidance.created` Fires when an earnings release contains forward guidance, minutes after `earnings.created` once we finish analyzing the release. Shape: [release-level](#release-level), carrying `forward_guidance`. Entries match [`GET /kpi/guidance`](/api/kpi/guidance). ### `income_statements.created` Fires when a filing's income statements are extracted, within minutes of a 10-K, 10-Q, 20-F, or 6-K being processed. Shape: [filing-level](#filing-level), carrying `income_statements`. Entries match [`GET /financials/income-statements`](/api/financials/income-statements). ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "1d2f5a80-93c4-4e0f-8a1c-6b7d2e9f4a31", "type": "income_statements.created", "api_version": "2026-05-20", "livemode": true, "created": 1783208305, "data": { "object": { "ticker": "TXN", "accession_number": "0000097476-26-000060", "filing_date": "2026-04-23", "form_type": "10-Q", "income_statements": [ { "ticker": "TXN", "report_period": "2026-03-31", "fiscal_period": "2026-Q1", "period": "quarterly", "currency": "USD", "revenue": 4742000000.0, "net_income": 1364000000.0, "...": "see the Income Statements API reference" } ] } } } ``` A filing usually produces one entry per array. When we can also compute a trailing-twelve-months view from it, a second entry with `"period": "ttm"` appears alongside the quarterly or annual one. Entries are ordered by period type, so on annual filings the `ttm` entry comes first. ### `income_statement_segments.created` Fires when a filing reports income statement segment breakdowns. This is the most common of the three segment events. Shape: [filing-level](#filing-level), carrying `income_statement_segments`. Entries match [`GET /financials/income-statements/segments`](/api/financials/income-statement-segments). ### `inflation.created` Fires when a new month of consumer price index data is published, within hours of the monthly release. One event per reference month, carrying every series we track. Shape: [print-level](#print-level), carrying `inflation`. The array is identical to the body of [`GET /macro/inflation/snapshot`](/api/macro/inflation/snapshot): one entry per series, each with the index level and the month-over-month and year-over-year percent changes. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "c7e2a9f4-1b3d-4e5f-8a6b-9c0d1e2f3a4b", "type": "inflation.created", "api_version": "2026-05-20", "livemode": true, "created": 1789560000, "data": { "object": { "date": "2026-08-01", "inflation": [ { "series": "cpi_all_sa", "date": "2026-08-01", "value": 334.131, "change_1m_pct": 0.4, "change_12m_pct": 3.4 }, { "series": "cpi_all_nsa", "date": "2026-08-01", "value": 334.98, "change_1m_pct": 0.3, "change_12m_pct": 3.4 } ] } } } ``` The live event carries one entry per series, twelve in total. `date` is the reference month as its first day, not the release date, the same convention the Inflation API uses. ### `insider_ownership.created` Fires when an insider reports positions they hold rather than trades: SEC Form 3 initial ownership statements, Form 5 filings that include holdings, and their amendments (`3/A`, `5/A`). One event per filing, delivered once daily in the early morning UTC covering the previous day's filings. Shape: [filing-level](#filing-level), carrying `insider_ownership`. Entries match [`GET /insider-ownership`](/api/insider-ownership). A single Form 5 that reports both transactions and holdings fires **both** events: one `insider_trades.created` and one `insider_ownership.created`, sharing the same `accession_number`. Each entry describes one held position: | Field | Type | Description | | ------------------------------ | -------------- | -------------------------------------------------------------------------------------- | | `ticker` | string | Ticker of the issuer whose securities are held. | | `issuer` | string | Issuer company name. | | `name` | string | The insider's name. | | `title` | string \| null | The insider's role at the issuer. | | `is_board_director` | boolean | Whether the insider sits on the board. | | `is_officer` | boolean | Whether the insider is an officer of the issuer. | | `is_ten_percent_owner` | boolean | Whether the insider owns 10%+ of the issuer. | | `form_type` | string | `3`, `3/A`, `5`, or `5/A`. | | `filing_date` | string (date) | Date the form was filed with the SEC. | | `as_of_date` | string (date) | Date the position is stated as of. | | `accession_number` | string | The SEC accession number of the filing. | | `holding_type` | string | `common` or `derivative`. Derivative-only fields below are `null` on `common` entries. | | `security_title` | string | Title of the held security. | | `shares_owned` | number | Shares (or units) beneficially owned. | | `direct_or_indirect` | string | `D` (held directly) or `I` (held indirectly). | | `nature_of_ownership` | string \| null | For indirect holdings, the ownership vehicle (e.g. a trust or LLC). | | `conversion_or_exercise_price` | number \| null | Derivative only: conversion or exercise price. | | `exercise_date` | string \| null | Derivative only: date first exercisable. | | `expiration_date` | string \| null | Derivative only: expiration date. | | `underlying_security_title` | string \| null | Derivative only: title of the underlying security. | | `underlying_security_shares` | number \| null | Derivative only: number of underlying shares. | ### `insider_trades.created` Fires when a company insider reports buying or selling stock: SEC Form 4, Form 5 annual statements that include transactions, and their amendments (`4/A`, `5/A`). One event per filing, delivered once daily in the early morning UTC covering the previous day's filings. Shape: [filing-level](#filing-level), carrying `insider_trades`, with one entry per reported transaction in filing order. Entries match [`GET /insider-trades`](/api/insider-trades). ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "8f3c0a51-2f6e-4d1b-9a77-c9d4e2b81f02", "type": "insider_trades.created", "api_version": "2026-05-20", "livemode": true, "created": 1783148405, "data": { "object": { "ticker": "NVDA", "accession_number": "0001045810-26-000214", "filing_date": "2026-07-06", "form_type": "4", "insider_trades": [ { "ticker": "NVDA", "issuer": "NVIDIA Corp", "name": "JENSEN HUANG", "title": "CEO", "is_board_director": true, "filing_date": "2026-07-06", "report_period": "2026-07-02", "transaction_date": "2026-07-02", "transaction_code": "S", "transaction_type": "Open market sale", "transaction_shares": 75000.0, "transaction_price_per_share": 157.32, "transaction_value": 11799000.0, "shares_owned_before_transaction": 75600000.0, "shares_owned_after_transaction": 75525000.0, "security_title": "Common Stock" } ] } } } ``` **Amendments.** An amendment (`4/A`, `5/A`) is its own filing with its own `accession_number`, so it fires its own event containing the complete, amended set of transactions. Treat its contents as replacing what the original filing reported. ### `non_gaap_metrics.created` Fires when an earnings release contains non-GAAP metrics, minutes after `earnings.created`. Shape: [release-level](#release-level), carrying `non_gaap_metrics`. Entries match [`GET /kpi/non-gaap`](/api/kpi/non-gaap). ### `operating_kpis.created` Fires when operating KPIs are extracted from a new earnings release, minutes after `earnings.created`. Shape: [release-level](#release-level), carrying `operating_kpis`. Entries match [`GET /kpi/metrics`](/api/kpi/metrics). ### `yield_curve.created` Fires when a new business day of the Treasury yield curve is published, the same evening. One event per business day. Shape: [print-level](#print-level), carrying `yield_curve`. The object is identical to the body of [`GET /macro/yield-curve/snapshot`](/api/macro/yield-curve/snapshot): the date plus one key per tenor, `null` where a tenor was not published that day. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "e1f4b7a2-6c8d-4a9e-b0f1-2d3c4b5a6e7f", "type": "yield_curve.created", "api_version": "2026-05-20", "livemode": true, "created": 1789431000, "data": { "object": { "date": "2026-09-14", "yield_curve": { "date": "2026-09-14", "1_month": 3.94, "1_5_month": 4.0, "2_month": 4.06, "3_month": 4.11, "4_month": 4.18, "6_month": 4.18, "1_year": 4.37, "2_year": 4.65, "3_year": 4.73, "5_year": 4.8, "7_year": 4.88, "10_year": 4.97, "20_year": 5.37, "30_year": 5.34 } } } } ``` ## Handling multiple earnings events A single quarter of earnings can produce more than one `earnings.created` event as the SEC filing chain progresses: 1. The **8-K** earnings release fires first, typically hours after announcement. 2. The **10-Q** (or **10-K** for the fiscal-year quarter) follows 30 to 45 days later with the full GAAP-audited numbers, segments, and footnotes-derived metrics. Both events have the same `(ticker, report_period)` but different `accession_number`s and different `data.object.source_type` values (`"8-K"` vs `"10-Q"` vs `"10-K"`). Three reasonable ways to handle this: * **Dedupe by `(ticker, report_period)`** — process the first event you see, ignore the later one. Use when latency matters more than completeness. * **Always process the most recent `source_type`** — keep the 10-Q's richer data, discard the earlier 8-K once it arrives. Use when you need the full GAAP record. * **Process both** — emit your downstream signal twice. Use when you have separate "first signal" and "final record" consumers, such as real-time alerting plus an analytics warehouse. The dedup key on our side is `event.id`, the same one we use for retry idempotency. The dedup key on **your** side is `(ticker, report_period)` if you want once-per-quarter semantics. Foreign issuers and microcaps that don't file 8-Ks fire only one event per period (the 10-Q, 10-K, or 20-F). ## Timing summary | Family | When it arrives | | ------------------------------ | ---------------------------------------------------------------------------------------------------- | | Earnings | Within minutes of the filing hitting EDGAR. | | Financial statements, segments | Within minutes of a 10-K, 10-Q, 20-F, or 6-K being processed. | | Earnings intelligence | Minutes after `earnings.created`, once analysis completes. | | Insider activity | Once daily, early morning UTC, covering the previous day's filings. | | Filings | Within minutes of a 10-K, 10-Q, or 8-K being processed. | | Macroeconomics | The evening a new yield curve day is published; within hours of each monthly consumer price release. | ## See also * [Webhooks reference](/webhooks) — delivery, retries, signature verification, debugging. * [How to set up webhooks](/guides/setup-webhooks) — step-by-step with a working Python receiver.