# Financial Datasets > Financial Datasets is a stock market API with financial data for 27,000+ tickers over 30+ years, including financial statements, equity prices, insider transactions, SEC filings, and more. > ## Agent Instructions > The Financial Datasets API is served at https://api.financialdatasets.ai. Authenticate with the `X-API-KEY` header; create keys at https://financialdatasets.ai. Agents can open and fund their own account without a dashboard: see https://docs.financialdatasets.ai/agents.md. > Tool-using agents can call Financial Datasets without writing code through the hosted MCP server at https://mcp.financialdatasets.ai/. > The OpenAPI spec at https://financialdatasets.ai/openapi.json is the source of truth for request and response schemas. > The index of every docs page is at https://docs.financialdatasets.ai/llms.txt. Append .md to any docs URL to get that page as Markdown. # 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`). > [!NOTE] > > Have a wallet with USDC on Base? You can skip the account entirely and [pay per request with x402](/x402) on every documented GET data endpoint. Open an account when you need full history or the few endpoints x402 does not cover. ## 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. > [!NOTE] > > 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? > [card] [Full endpoint map](https://www.financialdatasets.ai/llms.txt) > > Every endpoint with parameters, in agent-readable llms.txt form. > [card] [Financial Statements](/api/financials/income-statements) > > Income statements, balance sheets, and cash flow statements. > [card] [Stock Prices](/api/prices/historical) > > Historical and real-time price data. > [card] [MCP Server](/mcp-server) > > Person at the keyboard? MCP with OAuth is the faster path. # Activist Investor API (SEC Schedule 13D) Source: https://docs.financialdatasets.ai/api/activist-ownership GET /activist-ownership Activist investor stakes in US public companies from SEC Schedule 13D filings: 2,400+ companies and 2,900+ activist filers since January 2025, updated within about 1 minute. ### Overview The Financial Datasets activist ownership API returns the activist stakes in US public companies, from SEC Schedule 13D filings. It covers 2,400+ companies and 2,900+ activist filers since January 2025, updated within about 1 minute. Every filing is parsed directly from SEC EDGAR ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### What is a Schedule 13D? An investor files a Schedule 13D after crossing 5% ownership of a company with intent to influence control, for example through a proxy fight, a push for a sale, or board seats. #### How fast do new 13D filings show up? Within about 1 minute of reaching SEC EDGAR. #### How far back does the data go? To January 2025, when the SEC's structured-data mandate for Schedules 13D and 13G took effect. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach the same 13D stakes through the [Financial Datasets MCP server](/mcp-server), which serves them from the [beneficial ownership API](/api/beneficial-ownership) with `type=activist`. An agent with a wallet can also pay per request with [x402](/x402), with no account. # Beneficial Ownership API (13D, 13G) Source: https://docs.financialdatasets.ai/api/beneficial-ownership GET /beneficial-ownership Holders of more than 5% of a US public company from SEC Schedules 13D and 13G: activist and passive stakes with full amendment history, for 6,400+ companies since January 2025. ### Overview The Financial Datasets beneficial ownership API returns the holders of more than 5% of a class of a company's shares, from SEC Schedules 13D (activist) and 13G (passive). It covers 6,400+ companies and 8,100+ filers since January 2025. Activist stakes are updated within about 1 minute and passive stakes daily. Every filing is parsed directly from SEC EDGAR ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### What is the difference between Schedule 13D and 13G? Both report a stake of more than 5%. A 13D holder may seek to influence control, for example through a proxy fight or board seats. A 13G holder certifies passive intent, and is typically a large asset manager. #### Can I see only activist or only passive holders? Yes. Set `type=activist` for Schedule 13D stakes or `type=passive` for Schedule 13G stakes. Leave `type` out to get both. #### Can I see how a stake changed over time? Yes. By default, each stake's current state is returned. Add `history=true` to get the full chain of original filings and amendments. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Company Profile API by CIK Source: https://docs.financialdatasets.ai/api/company/facts/cik GET /company/facts Basic facts about a public company by SEC CIK: name, ticker, sector, industry, exchange, location, and SIC code, for 28,000+ tickers, updated in real time. ### Overview Company facts includes data like name, CIK, sector, industry, exchange, location, and SIC code. 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') ``` # Company Profile API (Sector, CIK) Source: https://docs.financialdatasets.ai/api/company/facts/ticker GET /company/facts Basic facts about a public company by ticker: name, CIK, sector, industry, exchange, location, and SIC code, for 28,000+ tickers, updated in real time. ### Overview The Financial Datasets company facts API returns the basic facts about a public company by ticker: name, CIK, sector, industry, exchange, location, SIC code, a link to its SEC filings, and whether the company is still active. It covers 28,000+ tickers, updated in real time. To look a company up by SEC CIK, use [Facts (by CIK)](/api/company/facts/cik). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Can I look up a company by CIK instead of ticker? Yes. Pass `cik` instead of `ticker`. See [Facts (by CIK)](/api/company/facts/cik). #### Does it include SIC codes? Yes. Each company has its SIC code, with the SIC industry and SIC sector, next to its sector and industry. #### Which tickers are covered? 28,000+ tickers. Get the full list with a `GET` request to `https://api.financialdatasets.ai/company/facts/tickers/`. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Earnings API Source: https://docs.financialdatasets.ai/api/earnings GET /earnings Revenue, EPS, margins, and cash flow from each earnings release (8-K) and the later 10-Q or 10-K, with quarter-over-quarter and year-over-year changes. ### Overview The Financial Datasets earnings API returns the figures a US company reports for each quarter and year: revenue, EPS, margins, net income, cash, debt, and operating cash flow. The first entry for a period comes from the 8-K earnings release, so you get the numbers as soon as they are released. It covers 6,000+ tickers with 2+ years of history, updated within 5 seconds. For non-Enterprise customers, real-time earnings cover S\&P 500 companies. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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`. ### FAQ #### How fast do earnings show up? Within 5 seconds. For non-Enterprise customers, real-time earnings cover S\&P 500 companies. #### Why are some fields null? The first entry for a period comes from the 8-K earnings release, which is preliminary. A company may not report every figure there. The later 10-Q or 10-K usually fills the gaps. #### Where does the earnings data come from? From SEC filings only: 8-K, 10-Q, 10-K, and 20-F. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Earnings Feed API Source: https://docs.financialdatasets.ai/api/earnings/feed GET /earnings A feed of the newest earnings filings across 6,000+ covered companies, newest first, updated within 5 seconds. ### 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. # SEC Filing Sections API (10-K Items) Source: https://docs.financialdatasets.ai/api/filings/items GET /filings/items The raw text of one section of a 10-K, 10-Q, or 8-K, such as Item 1A Risk Factors or Item 7 MD&A, for 22,000+ US tickers with 30+ years of history. ### 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 > [tab] 10-K Filing > > ```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') > ``` > [tab] 10-Q Filing > > ```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') > ``` > [tab] 8-K Filing > > ```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') > ``` > [tab] Specific 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" } ``` # SEC Filings API (10-K, 10-Q, 8-K) Source: https://docs.financialdatasets.ai/api/filings/ticker GET /filings List the SEC filings (10-K, 10-Q, 8-K, and more) of 22,000+ US tickers, with 30+ years of history, updated in real time from SEC EDGAR. ### Overview The Financial Datasets SEC filings API lists every filing a US public company has submitted to the SEC, including 10-Ks, 10-Qs, and 8-Ks. It covers 22,000+ tickers with 30+ years of history, updated in real time, pulled directly from SEC EDGAR ([data provenance](/data-provenance)). To get the text of one section, such as Item 1A Risk Factors or Item 7 MD\&A, use the [Items endpoint](/api/filings/items). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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") ``` ### FAQ #### Which SEC forms are included? Every filing the company submits to EDGAR, including 10-K, 10-Q, and 8-K. Use `filing_type` to get one form, or repeat it to get several. #### How fast do new filings show up? New filings are added in real time. #### Can I get the text of a 10-K section? Yes. The [Items endpoint](/api/filings/items) returns the raw text of an item from a 10-K, 10-Q, or 8-K, such as Item 1A Risk Factors or Item 7 MD\&A, so you do not parse the full document. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Financial Metrics API (Historical) Source: https://docs.financialdatasets.ai/api/financial-metrics/historical GET /financial-metrics Historical financial ratios for 19,000+ US tickers with 30+ years of history: P/E, EV/EBITDA, ROE, margins, growth, and other annual, quarterly, and TTM metrics. ### Overview The Financial Datasets financial metrics API returns historical financial ratios and metrics for a stock ticker, such as P/E, EV/EBITDA, ROE, margins, and growth rates, by year, by quarter, or trailing twelve months (TTM). It covers 19,000+ US tickers with 30+ years of history, updated within 1 second. The metrics are based on financial statements parsed directly from SEC filings ([data provenance](/data-provenance)). For the latest values, use the [Snapshot](/api/financial-metrics/snapshot) endpoint. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Which metrics are included? Valuation, profitability, efficiency, liquidity, leverage, growth, and per share metrics. Examples are P/E, P/B, EV/EBITDA, free cash flow yield, gross margin, ROE, ROIC, current ratio, debt to equity, revenue growth, and EPS. #### Can I get quarterly or TTM metrics? Yes. Set `period` to `annual`, `quarterly`, or `ttm`. #### Can I get metrics for a past date range? Yes. Filter with `report_period_gte` and `report_period_lte`, for example `report_period_gte=2020-01-01` and `report_period_lte=2024-01-01`. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Financial Metrics API (Snapshot) Source: https://docs.financialdatasets.ai/api/financial-metrics/snapshot GET /financial-metrics/snapshot The current financial ratios and metrics of a US stock, including market cap, P/E, EV/EBITDA, margins, and growth, for 13,000+ tickers, updated within 1 second. ### 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') ``` # Financial Statements API Source: https://docs.financialdatasets.ai/api/financials/all-financial-statements GET /financials Income statements, balance sheets, and cash flow statements for 19,000+ US tickers in one call, with 30+ years of history, plus UK and French companies. ### Overview The Financial Datasets financial statements API returns a company's income statement, balance sheet, and cash flow statement in one call, by year, by quarter, or trailing twelve months (TTM). It covers 19,000+ US tickers with 30+ years of history, updated within 1 second, parsed directly from SEC filings ([data provenance](/data-provenance)). Delisted companies are included, so backtests built on this data are free of survivorship bias. It also covers 674 UK companies and 376 French companies, annual only ([market coverage](/market-coverage)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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 financials from the response financials = response.json().get('financials') ``` ### FAQ #### Are delisted companies included? Yes. Every SEC filer is covered, active and delisted, so a backtest sees the companies that failed as well as the ones that survived. #### Can I get all three statements in one call? Yes. This endpoint returns the income statement, balance sheet, and cash flow statement together. Each is also available on its own endpoint. #### Which periods are available? Annual, quarterly, and TTM for US companies. Annual only for UK and French companies. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Segmented Financials API (All Segments) Source: https://docs.financialdatasets.ai/api/financials/all-segments GET /financials/segments Segment breakdowns from the income statement, balance sheet, and cash flow statement in one call, such as revenue by product and capex by segment, for 6,400+ US tickers with 15+ years of history. ### 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') ``` # As-Reported Financial Statements API Source: https://docs.financialdatasets.ai/api/financials/as-reported GET /financials/as-reported Income statements, balance sheets, and cash flow statements as the company filed them: each line with its label, value, and place in the statement, from 2010 onward. ### Overview The Financial Datasets as-reported financial statements API returns a company's income statement, balance sheet, and cash flow statement as the company filed them: every line in the company's own order, with its value and its place in the statement's hierarchy. The [standardized statements](/api/financials/income-statements) map every company onto the same fields so companies compare. The as-reported statements keep the lines the company actually reported. They are parsed directly from SEC filings ([data provenance](/data-provenance)) and are available from 2010 onward. UK and French companies are also covered, annual only ([market coverage](/market-coverage)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. To get started, please create an account and grab your **API key** at [financialdatasets.ai](https://financialdatasets.ai). ### Endpoints | Statement | Endpoint | | - | - | | All three statements | `GET /financials/as-reported` | | Income statement | `GET /financials/income-statements/as-reported` | | Balance sheet | `GET /financials/balance-sheets/as-reported` | | Cash flow statement | `GET /financials/cash-flow-statements/as-reported` | ### Filtering the Data * `ticker`, `cik`, or `isin`: one is required. * `market`: `US` (the default), `UK`, or `FR`. Or pass `isin` alone for a UK or French company. * `period` (required): `annual` or `quarterly`. There is no `ttm`. UK and French companies are annual only. * `limit`: the maximum number of periods to return. Each page holds up to 10 periods, linked by `next_page_url`. * `report_period`, `report_period_gte`, `report_period_lte`, `report_period_gt`, `report_period_lt`: filter by report period date (`YYYY-MM-DD`). ### Response Each period carries `ticker`, `report_period`, `fiscal_period`, `period`, `currency`, `accession_number`, and `filing_url`. The all-statements endpoint returns `income_statement`, `balance_sheet`, and `cash_flow_statement` objects per period under `financials`; any of the three may be `null` when data is missing. The single-statement endpoints return one statement per period under `income_statements`, `balance_sheets`, or `cash_flow_statements`. Each statement holds `line_items`, a tree of nodes: | Field | Meaning | | - | - | | `label` | The label as printed on the face of the filing. | | `full_label` | The canonical taxonomy label for the underlying concept. | | `value` | The numeric value as reported. `null` for section headers and subtotals with no direct value. | | `children` | The nested line items beneath this row. | ### Example ```python As-Reported 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 params = { "ticker": "AAPL", # stock ticker "period": "annual", # annual or quarterly "limit": 2, # number of periods to return } # make API request url = "https://api.financialdatasets.ai/financials/as-reported" response = requests.get(url, headers=headers, params=params) # parse financials from the response financials = response.json().get("financials") # print the latest income statement as an indented tree def print_lines(nodes, depth=0): for node in nodes: print(" " * depth + f"{node['label']}: {node['value']}") print_lines(node.get("children", []), depth + 1) print_lines(financials[0]["income_statement"]["line_items"]) ``` ### FAQ #### What is the difference between as-reported and standardized statements? Standardized statements map every company onto the same fields, such as `revenue` and `net_income`, so you can compare companies. As-reported statements keep each company's own lines, order, and hierarchy, so you see what the filing shows. #### How far back does the data go? To 2010. #### Which periods are available? Annual and quarterly for US companies. Annual only for UK and French companies. There is no TTM. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). Its financial statements tool returns the as-reported line items when `as_reported` is true. # Balance Sheet Segments API Source: https://docs.financialdatasets.ai/api/financials/balance-sheet-segments GET /financials/balance-sheets/segments Assets, goodwill, and long-lived assets by business segment, as reported in 10-K and 10-Q filings, for 6,200+ US tickers with 15+ years of history. ### 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 Sheet API Source: https://docs.financialdatasets.ai/api/financials/balance-sheets GET /financials/balance-sheets Balance sheets for 19,000+ US tickers with 30+ years of history: assets, liabilities, and shareholders equity, plus UK and French companies. ### 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 balance_sheets from the response balance_sheets = response.json().get('balance_sheets') ``` # Cash Flow Segments API Source: https://docs.financialdatasets.ai/api/financials/cash-flow-statement-segments GET /financials/cash-flow-statements/segments Capital expenditure by business segment, as reported in 10-K and 10-Q filings, for 5,900+ US tickers with 15+ years of history. ### 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 Statement API Source: https://docs.financialdatasets.ai/api/financials/cash-flow-statements GET /financials/cash-flow-statements Cash flow statements for 19,000+ US tickers with 30+ years of history: operating, investing, and financing cash flows, plus UK and French companies. ### 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 cash_flow_statements from the response cash_flow_statements = response.json().get('cash_flow_statements') ``` # Segmented Revenue API Source: https://docs.financialdatasets.ai/api/financials/income-statement-segments GET /financials/income-statements/segments Revenue by product and business segment, plus segment operating income and depreciation, as reported in 10-K and 10-Q filings: 6,400+ US tickers, 15+ years of history. ### Overview The Financial Datasets income statement segments API returns a company's revenue by product line and by business segment, plus operating income and depreciation by segment, as reported in its 10-K and 10-Q filings. It covers 6,400+ US tickers with 15+ years of history, updated within 1 second, parsed directly from SEC filings ([data provenance](/data-provenance)). To get balance sheet and cash flow segments in the same call, use [All Segmented Financials](/api/financials/all-segments). You can call it as a REST endpoint with an API key, or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Can I get revenue by product and by region? Yes, when the company reports it that way. For example, Apple reports revenue by product (iPhone, Mac, iPad, Services, Wearables) and by geographic segment (Americas, Europe, Greater China, Japan, Rest of Asia Pacific). #### Are quarterly segments available? Yes. Set `period` to `annual` or `quarterly`. #### Can I get balance sheet and cash flow segments? Yes. Use [Balance Sheet Segments](/api/financials/balance-sheet-segments) for assets, goodwill, and long-lived assets, [Cash Flow Statement Segments](/api/financials/cash-flow-statement-segments) for capital expenditure, or [All Segmented Financials](/api/financials/all-segments) for all three statements in one call. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach segment data through the [Financial Datasets MCP server](/mcp-server), which returns the breakdowns from all three statements in one call. An agent with a wallet can also pay per request with [x402](/x402), with no account. # Income Statement API Source: https://docs.financialdatasets.ai/api/financials/income-statements GET /financials/income-statements Income statements for 19,000+ US tickers with 30+ years of history: annual, quarterly, and TTM revenue, expenses, and net income, plus UK and French companies. ### Overview The Financial Datasets income statement API returns revenue, expenses, and net income for a stock ticker, by year, by quarter, or trailing twelve months (TTM). It covers 19,000+ US tickers with 30+ years of history, updated within 1 second, parsed directly from SEC filings ([data provenance](/data-provenance)). It also covers 674 UK companies and 376 French companies, annual only ([market coverage](/market-coverage)). The same API serves [balance sheets](/api/financials/balance-sheets) and [cash flow statements](/api/financials/cash-flow-statements), or all three in [one call](/api/financials/all-financial-statements). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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 income_statements from the response income_statements = response.json().get('income_statements') ``` ### FAQ #### Where does the income statement data come from? Directly from the 10-K, 10-Q, and 8-K filings on SEC EDGAR. The original XBRL and HTML filings are parsed, and the line items are normalized so companies compare. #### Are delisted companies included? Yes. Delisted companies are included, so backtests are free of survivorship bias. #### Can I get UK or French income statements? Yes. Add `market=UK` or `market=FR` to the ticker, or pass the company's `isin`. These markets are annual only, in the company's reporting currency. See the [UK guide](/guides/get-uk-fundamentals-python) and the [France guide](/guides/get-france-fundamentals-python). #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Financial Line Items API Source: https://docs.financialdatasets.ai/api/financials/search-line-items POST /financials/search/line-items Pull chosen line items, such as revenue, net income, or free cash flow, from the financial statements of a list of tickers in one request. 19,000+ US tickers, 30+ years. ### 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 API Source: https://docs.financialdatasets.ai/api/financials/search-screener POST /financials/search/screener Screen 17,000+ US stocks by revenue, P/E, margins, debt, growth, sector, and industry, using the latest financial statement and financial metrics data, or as of any date since 2010 for backtests. ### Overview The Financial Datasets stock screener API returns the stocks that match your filters on financial statement fields, financial metrics, sector, and industry. It covers 17,000+ US tickers and screens the latest reported data, updated within 1 second. With `as_of` it screens the data that was public on any date since 2010, for backtests without lookahead. Financial statement data is parsed directly from SEC filings ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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, or any date since 2010-03-01 with `as_of` | 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. * `order_by` (object, optional): Sort the matches before the limit applies, for example `{"field": "market_cap", "direction": "desc"}`. `field` is any numeric filter field; `direction` is `asc` or `desc` (default `desc`). Without it, results come back sorted by ticker. The sort field is added to every result row. * `as_of` (date, optional): Screen as of this date, `YYYY-MM-DD`. See [Point-in-time screening](#point-in-time-screening-for-backtests). * `currency` (string, optional): The currency of the statement values. Defaults to `USD`. A company is on the screen while its latest reported period is at most 180 days old. That is the longest legal gap between a period end and the next filing, so a company between quarters stays on the screen and a company that stopped filing drops off. **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) `in` works on every field: a list of numbers for a numeric field, a list of strings for `sector`, `industry`, and `ticker`. ### 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", ] ``` > [!NOTE] > > **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. ### Point-in-time screening for backtests Add `as_of` to screen on the data that was public on that date. For each company, the screener takes the newest filing it had made public on or before `as_of` and applies your filters to that filing. A report filed after `as_of` is never used, even when its period ends before `as_of`. This is the universe a backtest could have picked from on that day, with no lookahead. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} // Send JSON Request { "as_of": "2024-01-15", "filters": [ { "field": "market_cap", "operator": "gt", "value": 10000000000 }, { "field": "revenue", "operator": "gt", "value": 1000000000 } ], "order_by": { "field": "market_cap", "direction": "desc" }, "limit": 2 } ``` ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} // Receive JSON Response { "results": [ { "ticker": "AAPL", "filing_date": "2023-11-03", "report_period": "2023-09-30", "currency": "USD", "market_cap": 2676736860720.0, "revenue": 383285000000.0, "sector": "Information Technology", "industry": "Technology Hardware, Storage & Peripherals" }, { "ticker": "MSFT", "filing_date": "2023-10-24", "report_period": "2023-09-30", "currency": "USD", "market_cap": 2346736830381.75, "revenue": 218310000000.0, "sector": "Information Technology", "industry": "Software" } ], "as_of": "2024-01-15", "coverage_start": "2010-03-01" } ``` Every row carries `filing_date`, the day the matched filing became public, and `report_period`, the period it covers. The response carries `as_of` and `coverage_start`, the earliest date you can screen as of. > [!NOTE] > > * `as_of` must be between `coverage_start` (2010-03-01) and today. A date outside that range returns a 400 that names the earliest date. > * `stock_price` is not available with `as_of`. Market cap and the price ratios (`pe_ratio`, `pb_ratio`, `ps_ratio`, `ev_ebitda_ratio`, `ev_revenue_ratio`) are as computed when the filing was processed, not recomputed at the close of `as_of`. > * The 180-day rule applies to `as_of` too: a company is on the screen while its latest period on that date is at most 180 days old. ### 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("---") ``` ### FAQ #### Which fields can I screen on? Income statement, balance sheet, cash flow statement, and financial metrics fields, plus `sector` and `industry`. The full list is in [Available Filters](#available-filters), or fetch it with `GET /financials/search/screener/filters`. #### How do I screen by sector or industry? Use `sector` or `industry` with the `eq` or `in` operator. Values are case-insensitive and follow the GICS classification. #### Can I run the screen as of a past date for a backtest? Yes. Add `as_of` (`YYYY-MM-DD`, from 2010-03-01). The screen uses only filings that were public on that date, so a backtest never sees a report filed later. See [Point-in-time screening](#point-in-time-screening-for-backtests). #### Can I sort the results, for example the top 50 by market cap? Yes. Add `order_by`, for example `{"field": "market_cap", "direction": "desc"}` with `"limit": 50`. The sort runs before the limit, so you get the top rows without fetching the whole universe. #### Why did a company disappear from the screen? Its latest reported period is more than 180 days old, which means it has missed a filing deadline or stopped filing. It returns when its next filing is processed. #### Do I enter margins as percentages? No. Margins and ratios are decimals: a 10% operating margin is `0.10`, not `10`. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). # ETFs Holding a Stock API Source: https://docs.financialdatasets.ai/api/index-funds/holding GET /index-funds The ETFs and index funds whose latest filing holds a given stock, with each fund's weight in it, from SEC fund holdings filings: 4,500+ securities, updated daily. ### 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') ``` # ETF Holdings API Source: https://docs.financialdatasets.ai/api/index-funds/ticker GET /index-funds The holdings of an ETF or index fund and each position's weight, from SEC fund holdings filings: 500+ funds, 5+ years of history, updated daily. ### Overview The Financial Datasets ETF holdings API returns the full list of holdings of an ETF or index fund and each position's percent of net assets, largest first, with a fund header that carries the as-of period and coverage counts. It covers 500+ funds with 5+ years of history, updated daily, from SEC fund holdings filings. To see which funds hold a given stock, use [Funds (by holding)](/api/index-funds/holding). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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`). `name` is 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') ``` ### FAQ #### Which funds are covered? 500+ ETFs and index funds. Get the list with a free request to `/index-funds/tickers/`. It needs no API key. #### Can I see what a fund held on a past date? Yes. Pass `as_of=YYYY-MM-DD` to get the composition in effect on or before that date. Without `as_of`, you get the fund's most recent filing. #### Does it include bonds and cash? Yes. Every position is returned, including bonds, derivatives, and cash, each labeled with an `asset_class` of `equity`, `bond`, or `other`. Pass `asset_class=equity` to get equities only. `ticker` is `null` for securities without a US listing. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Insider Ownership API (Forms 3, 5) Source: https://docs.financialdatasets.ai/api/insider-ownership GET /insider-ownership What officers, directors, and 10% owners hold, from SEC Forms 3 and 5: initial and annual ownership statements for 6,500+ companies and 40,000+ insiders since January 2021, updated daily. ### Overview The Financial Datasets insider ownership API returns what public company insiders, such as CEOs, CFOs, directors, and 10% owners, hold, from their ownership statements on SEC Form 3 and Form 5. It covers 6,500+ companies and 40,000+ insiders since January 2021, updated daily. Every filing is parsed directly from SEC EDGAR ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### What is the difference between insider ownership and insider trades? Ownership statements show what an insider holds. Trades are the buys and sells in between. Use the [insider trades API](/api/insider-trades) for the trades. #### Does it include options and RSUs? Yes. Each statement lists the positions as reported, including options and RSUs, with the exercise price, expiration date, and underlying shares where the filing gives them. #### Can I see shares held through trusts or LLCs? Yes. Each position says whether it is held directly or indirectly, and gives the nature of the indirect ownership. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Insider Trading API (SEC Form 4) Source: https://docs.financialdatasets.ai/api/insider-trades GET /insider-trades SEC Form 4 insider trades for 8,200+ US stocks: buys and sells by officers and directors, with 15+ years of history, updated within 10 seconds. ### Overview The Financial Datasets insider trades API returns the stock buys and sales that public company insiders, such as CEOs, CFOs, and directors, report to the SEC on Form 4 and Form 5. It covers 8,200+ US tickers with 15+ years of history, updated within 10 seconds. Every trade is parsed directly from SEC EDGAR ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Where does the insider trading data come from? Directly from SEC EDGAR. Each Form 4 and Form 5 filing is parsed into a structured record with the transaction type, share count, price, and the insider's ownership. #### How fast do new insider trades show up? New trades are added within 10 seconds. #### Can I filter by insider or by type of trade? Yes. Filter by `name` (list the names with `/insider-trades/names/`), by `transaction_type` (for example "Open market sale"), by `form_type`, and by `filing_date` range. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # 13F Holdings API (by Investor) Source: https://docs.financialdatasets.ai/api/institutional-holdings/investor GET /institutional-holdings The full 13F equity portfolio of any institutional investment manager, by SEC CIK: positions, share counts, and market values, from SEC 13F filings. ### 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') ``` # Institutional Holdings API (SEC 13F) Source: https://docs.financialdatasets.ai/api/institutional-holdings/ticker GET /institutional-holdings The institutional investors that hold a stock and the size of each position, from SEC 13F filings: 18,000+ US tickers, 5+ years of history, updated daily. ### Overview The Financial Datasets institutional holdings API returns the institutional investors that hold a given stock, with the size of each position, largest first. The data comes from SEC Form 13F filings, parsed directly from SEC EDGAR ([data provenance](/data-provenance)). It covers 18,000+ US tickers with 5+ years of history, updated daily. To see every stock one investor holds, use [Holdings (by investor)](/api/institutional-holdings/investor). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Where does the 13F data come from? Directly from the Form 13F filings on SEC EDGAR. Each filing is a quarterly snapshot of an institution's positions. #### How often is it updated? Daily, as new 13F filings arrive. #### Can I see one investor's full portfolio? Yes. [Holdings (by investor)](/api/institutional-holdings/investor) returns the 13F portfolio of an institutional investment manager by SEC CIK. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # IPO Data API (S-1 and F-1 Filings) Source: https://docs.financialdatasets.ai/api/ipos GET /ipos Every SEC Form S-1, S-1/A, F-1, F-1/A, 424B4, and 424B1 since July 2026, minutes after SEC acceptance, with the proposed ticker, exchange, and expected price, plus full pre-IPO financial statements for IPO-grade companies. ### Overview The Financial Datasets IPO API returns a real-time feed of the SEC filings that companies make before going public: every Form S-1, S-1/A, F-1, F-1/A, 424B4, and 424B1 since July 2026, minutes after SEC acceptance. For IPO-grade filings, it also returns the company's full pre-IPO financial statements. You can call it as a REST endpoint with an API key, or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. This is premium data, so each call counts as more than one request. 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. Some companies file before they have chosen a ticker symbol. When an IPO-grade filing states no symbol on its cover, we serve it under a placeholder ticker made from the company's name (for example `ANTHROPIC` or `OPENAI`) and mark the item with `is_ticker_placeholder: true`. Once a later filing prints the real symbol, the company moves to it and the placeholder retires. 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. > [!NOTE] > > 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, S-1/A, F-1, F-1/A, 424B4 and 424B1 | Since July 2026 | Real-time (minutes after SEC acceptance) | ### 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`. There is no maximum: larger results are paged, see [pagination](/guides/pagination). The `ticker` parameter matches the proposed ticker from the filing's cover page, or the placeholder ticker for filings that state no symbol. 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') ``` ### FAQ #### Which filings are included? Every SEC Form S-1, S-1/A, F-1, F-1/A, 424B4, and 424B1 filed since July 2026. Each filing is classified as `ipo`, `shell_company`, `spac`, `resale`, or `other`. Pass `classification=ipo` to get only real operating companies registering to list on an exchange. #### Can I see a company's financials before it goes public? Yes. For IPO-grade filings, the income statements, balance sheets, and cash flow statements in the prospectus are extracted, including interim periods, and embedded under `financials`. `financials` is `null` until extraction completes. Then `status` is `COMPLETED`. #### What if the company has not chosen a ticker yet? An IPO-grade filing with no symbol on its cover is served under a placeholder ticker made from the company's name, for example `ANTHROPIC`, and marked with `is_ticker_placeholder: true`. When a later filing prints the real symbol, the company moves to it. #### How fast do new filings show up? Minutes after the SEC accepts the filing. # Earnings Guidance API Source: https://docs.financialdatasets.ai/api/kpi/guidance GET /kpi/guidance Forward guidance from company earnings releases, such as revenue, EPS, and margin outlooks, as ranges, point estimates, or directional signals, for 600+ US tickers with 3+ years of history. ### 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 30 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. # Company KPI Data API Source: https://docs.financialdatasets.ai/api/kpi/metrics GET /kpi/metrics Operating KPIs from earnings releases that standard financial statements leave out, such as airline load factor and bank CET1 ratio, for 600+ US tickers with 3+ years of history, updated within 30 seconds. ### Overview The Financial Datasets KPI metrics API returns the operating KPIs that companies report in their earnings releases but that are not in standard financial statements, such as airline load factor, bank CET1 ratio, and REIT FFO per share. It covers 600+ US tickers with 3+ years of history, updated within 30 seconds. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. This is premium data, so each call counts as more than one request. Examples by sector: * **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 30 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. ### FAQ #### Which KPIs are covered? Sector-specific operating metrics. Examples: load factor and CASM-ex-fuel for airlines, CET1 ratio and net interest margin for banks, FFO per share and occupancy for REITs, comparable store sales for retail, and data center revenue for semiconductors. List the covered tickers with `/kpi/metrics/tickers/` and the sectors with `/kpi/metrics/sectors/`. #### Can I check each number against the source? Yes. Each metric includes `source_text`, the text from the source document, and `source_url`, a link to that document. When a text-level citation is available, the link highlights the source text in the browser. #### Can I get company guidance and non-GAAP metrics too? Yes. [Guidance](/api/kpi/guidance) returns forward guidance from earnings releases as ranges, point estimates, or directional signals. [Non-GAAP Metrics](/api/kpi/non-gaap) returns adjusted metrics, such as adjusted EPS, with their GAAP equivalents and key adjustments. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Non-GAAP Metrics API (Adjusted EPS) Source: https://docs.financialdatasets.ai/api/kpi/non-gaap GET /kpi/non-gaap Adjusted metrics from earnings releases, such as adjusted EPS, adjusted EBITDA, and free cash flow, each with its GAAP equivalent and key adjustments, for 600+ US tickers with 3+ years of history. ### 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 30 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. # GPU Rental Price API (H100, B200) Source: https://docs.financialdatasets.ai/api/macro/gpu-prices/historical GET /macro/gpu-prices Daily rental prices for NVIDIA H100, H200, B200, and B300 GPUs in US dollars per GPU hour, from August 2026 to today, updated hourly, with the provider spread and the 1, 7, and 30 day changes. ### Overview The Financial Datasets GPU prices API returns the daily rental price of one GPU model per request: what an hour of NVIDIA H100, H200, B200, or B300 compute costs on the open market, in US dollars per GPU hour. Each day carries the spread across providers behind the price and the change over 1, 7, and 30 days, computed for you. It covers 4 series from August 2026 to today, updated hourly. The source is the Computable GPU Index, published by Computable. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. The index is a reference rate built from the published on-demand prices of many cloud GPU providers. A new value is published every 15 minutes; we store one value per day, the newest print of each UTC day, and refresh today's value every hour. 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 | | - | - | - | | August 2026 to today | 4 | Hourly | ### Series | Series | What it is | Units | From | | - | - | - | - | | `h100` | NVIDIA H100 rental price index | USD per GPU hour | 2026-08-23 | | `h200` | NVIDIA H200 rental price index | USD per GPU hour | 2026-08-23 | | `b200` | NVIDIA B200 rental price index | USD per GPU hour | 2026-08-16 | | `b300` | NVIDIA B300 rental price index | USD per GPU hour | 2026-08-10 | You can fetch this list, with each series' first available date, with a free `GET` request to: [https://api.financialdatasets.ai/macro/gpu-prices/series/](https://api.financialdatasets.ai/macro/gpu-prices/series/) ### Reading the fields * `date` is the UTC day the value belongs to. The value is the newest print of that day; for today it is the newest print at the last hourly refresh, and `as_of` tells you when that was. * `value` is the price in US dollars per GPU hour. * `stability_band` is the standard deviation of the providers' prices behind `value`, in the same units. A wide band means providers disagree; a narrow band means a tight market. * `change_1d` is `value` minus the prior day's value, in dollars. `change_1d_pct`, `change_7d_pct`, and `change_30d_pct` are the percent changes from 1, 7, and 30 days earlier, rounded to two decimals. * A change is `null` when the comparison day has no value. * `attribution` names the source of the index. Please keep it when you display the data. ### Source and license The index is the Computable GPU Index, published by Computable under a Creative Commons Attribution license. Attribution: "Computable GPU Index by Computable — mcp.getcomputable.com". ### 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 with `series` and, optionally, `start_date` and `end_date`. ### Example ```python GPU 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 series = 'h100' start_date = '2026-09-01' end_date = '2026-09-28' # create the URL url = ( f'https://api.financialdatasets.ai/macro/gpu-prices' f'?series={series}' f'&start_date={start_date}' f'&end_date={end_date}' ) # make API request response = requests.get(url, headers=headers) # parse the daily prices from the response gpu_prices = response.json().get('gpu_prices') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "gpu_prices": [ { "series": "h100", "date": "2026-09-28", "value": 3.585166, "stability_band": 0.608466, "change_1d": 0.038145, "change_1d_pct": 1.08, "change_7d_pct": 0.2, "change_30d_pct": 3.8, "as_of": "2026-09-28T15:52:56Z" }, { "series": "h100", "date": "2026-09-27", "value": 3.547021, "stability_band": 0.605112, "change_1d": -0.002114, "change_1d_pct": -0.06, "change_7d_pct": -0.35, "change_30d_pct": 2.71, "as_of": "2026-09-28T00:20:09Z" } ], "attribution": "Computable GPU Index by Computable — mcp.getcomputable.com", "next_page_url": "https://api.financialdatasets.ai/macro/gpu-prices/?cursor=..." } ``` Rows come newest first, ten per page; follow `next_page_url` for the rest of the window. Without dates the window is the trailing 90 days. ### FAQ #### Where do the GPU prices come from? From the Computable GPU Index, published by Computable under a Creative Commons Attribution license. The index is a reference rate built from the published on-demand prices of many cloud GPU providers. Keep the `attribution` field when you display the data. #### How often is the price updated? The index publishes a new value every 15 minutes. The API stores one value per UTC day, the newest print of that day, and refreshes today's value every hour. #### What does `stability_band` mean? It is the standard deviation of the providers' prices behind `value`, in US dollars per GPU hour. A wide band means providers disagree. A narrow band means a tight market. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Latest GPU Rental Prices API Source: https://docs.financialdatasets.ai/api/macro/gpu-prices/snapshot GET /macro/gpu-prices/snapshot Today's rental price of H100, H200, B200, and B300 GPUs in US dollars per GPU hour, with the provider spread and the 1, 7, and 30 day changes, refreshed hourly. ### Overview The GPU Prices Snapshot API returns today's rental price of every GPU model we track, four rows, each with the spread across providers and the 1, 7, and 30 day percent changes computed for you. Pass `series` to get one row. The index is a reference rate built from the published on-demand prices of many cloud GPU providers. It is published every 15 minutes; the snapshot refreshes every hour, and `as_of` tells you when. 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 day | 4 | Hourly | ### Series Four GPU models: `h100`, `h200`, `b200`, `b300`. The full list is one free `GET` request away: [https://api.financialdatasets.ai/macro/gpu-prices/series/](https://api.financialdatasets.ai/macro/gpu-prices/series/) ### Reading the fields * `date` is the UTC day; `as_of` is when today's value was last refreshed. * `value` is the price in US dollars per GPU hour. * `stability_band` is the standard deviation of the providers' prices behind `value`, in the same units. * `change_1d` is the dollar change from the prior day. `change_1d_pct`, `change_7d_pct`, and `change_30d_pct` are percent changes from 1, 7, and 30 days earlier, rounded to two decimals. A change is `null` when the comparison day has no value. * `attribution` names the source of the index. Please keep it when you display the data. ### Source and license The index is the Computable GPU Index, published by Computable. ### 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 model instead of all four. ### Example ```python GPU Prices 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/gpu-prices/snapshot' # make API request response = requests.get(url, headers=headers) # parse the latest prices from the response gpu_prices = response.json().get('gpu_prices') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "gpu_prices": [ { "series": "h100", "date": "2026-09-28", "value": 3.585166, "stability_band": 0.608466, "change_1d": 0.038145, "change_1d_pct": 1.08, "change_7d_pct": 0.2, "change_30d_pct": 3.8, "as_of": "2026-09-28T15:52:56Z" }, { "series": "h200", "date": "2026-09-28", "value": 4.292195, "stability_band": 0.671639, "change_1d": -0.035353, "change_1d_pct": -0.82, "change_7d_pct": -0.87, "change_30d_pct": 1.67, "as_of": "2026-09-28T15:52:57Z" } ], "attribution": "Computable GPU Index by Computable — mcp.getcomputable.com" } ``` The live response has one row per model, four in total. # Inflation Data API (CPI, PCE) Source: https://docs.financialdatasets.ai/api/macro/inflation/historical GET /macro/inflation Monthly US CPI (from 1947) and PCE price index (from 1959) history in 14 series, including headline and core, with month-over-month and year-over-year changes, updated within minutes of each monthly release. ### Overview The Financial Datasets inflation API returns the monthly US Consumer Price Index (CPI) and the Personal Consumption Expenditures (PCE) price index, one series per request, with the month-over-month and year-over-year percent changes computed for you. It covers 14 series, with CPI from 1947 and PCE from 1959 to today, updated within minutes of each monthly release. The data comes directly from authoritative government sources ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. Values are index levels (1982-84 = 100 for CPI, 2017 = 100 for PCE); 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 (CPI), 1959 to today (PCE) | 14 | Within minutes of each monthly release | ### Series CPI: six concepts, each seasonally adjusted (`_sa`) and not seasonally adjusted (`_nsa`). PCE: headline and core, seasonally adjusted only (the source publishes no unadjusted series). | 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) | | `pce_all_sa` | PCE price index, all items | 1959 | | `pce_core_sa` | PCE price index, all items less food and energy | 1959 | 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. CPI for a month is published in the middle of the next month; PCE about two weeks after that. It is not the release date. * `value` is the published index level: 1982-84 = 100 for the CPI series, 2017 = 100 for the PCE series. The two bases are not comparable; the percent changes are. * `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`. The Fed's preferred measure is `change_12m_pct` of `pce_core_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 } ] } ``` ### FAQ #### Which series is the headline inflation rate? The headline inflation rate is `change_12m_pct` of `cpi_all_nsa`. The headline monthly figure is `change_1m_pct` of `cpi_all_sa`. The Fed's preferred measure is `change_12m_pct` of `pce_core_sa`. #### How fast is a new print available? Within minutes of each monthly release. CPI for a month is published in the middle of the next month, and PCE about two weeks after that. #### Are revisions included? Yes. History holds the latest published values. When a past month is revised, the stored value is replaced. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Latest CPI and PCE Inflation API Source: https://docs.financialdatasets.ai/api/macro/inflation/snapshot GET /macro/inflation/snapshot The latest month of all 14 US inflation series in one call, 12 CPI and 2 PCE, with month-over-month and year-over-year changes, updated within minutes of each monthly release. ### Overview The Inflation Snapshot API returns the most recent month of every inflation series we track, fourteen rows (twelve CPI, two PCE), 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 within minutes of each release: CPI in the middle of the month, PCE about two weeks later, so for part of each month the two families show different months. To receive each new 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 | 14 | Within minutes of each monthly release | ### Series CPI: 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`. PCE: `pce_all_sa` and `pce_core_sa`, seasonally adjusted only. 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 for CPI, 2017 = 100 for PCE). * `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`; the Fed's preferred measure is `change_12m_pct` of `pce_core_sa`. * 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 fourteen. ### 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, fourteen in total: the twelve CPI series on their newest month, then the two PCE series on theirs. # Central Bank Interest Rates API Source: https://docs.financialdatasets.ai/api/macro/interest-rates/historical GET /macro/interest-rates The daily policy rate of 10 major central banks, including the Federal Reserve, with 70+ years of history, updated the same afternoon for the Federal Reserve and weekly for the other banks. ### Overview The Financial Datasets interest rates API returns the policy rate of 10 major central banks as a daily series, one bank per request: one row per calendar day, newest first, with a rate change appearing on the first day the new rate is in effect. It covers 70+ years of history, updated the same afternoon for the Federal Reserve and weekly for the other banks. The data comes from authoritative sources that compile each central bank's official policy rate, and from the Federal Reserve's own releases. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. A Federal Reserve decision lands the same afternoon it is announced, dated the day it takes effect. The other banks' daily series is published once a week, so their newest day is typically two to nine days behind the calendar. For the Federal Reserve the rate is the midpoint of the target range (for example `3.875` for a 3.75 to 4.00 percent range). 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 | Frequency | Updated | | - | - | - | - | | 10 | 70+ years | Daily | Same afternoon for the Federal Reserve; weekly for the other banks | ### 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/) ### Window and pagination `bank` is required. `start_date` and `end_date` are optional and inclusive. With no dates the response covers the trailing five years; pass `start_date` to reach further back (for example `start_date=1954-07-01` for the whole Federal Reserve series). Responses are paged at 10 rows, newest first. When more rows remain the response carries `next_page_url`; request it as-is to continue. ### 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 the first page from the response interest_rates = response.json().get('interest_rates') next_page_url = response.json().get('next_page_url') # present while more rows remain ``` ### FAQ #### How far back does the history go? 70+ years. Pass `start_date=1954-07-01` to get the whole Federal Reserve series. With no dates, you get the trailing five years. #### How fast does a rate change show up? A Federal Reserve decision lands the same afternoon it is announced, dated the day it takes effect. The other banks' series is published once a week, so their newest day is typically two to nine days behind the calendar. #### What rate is shown for the Federal Reserve? The midpoint of the target range. For example, a 3.75 to 4.00 percent range is returned as `3.875`. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Current Central Bank Interest Rates API Source: https://docs.financialdatasets.ai/api/macro/interest-rates/snapshot GET /macro/interest-rates/snapshot The newest published policy rate of 10 major central banks in one call, with the date each rate is in effect, updated the same afternoon for the Federal Reserve and weekly for the other banks. ### Overview The Interest Rates Snapshot API returns the newest published policy rate of each of the 10 central banks we cover, with the date it is in effect. Pass `bank` to get one bank only. We source our data from authoritative sources that compile each central bank's official policy rate, and from the Federal Reserve's own releases. A Federal Reserve decision lands the same afternoon it is announced, dated the day it takes effect. The other banks' daily series is published once a week, so their newest day is typically two to nine days behind the calendar. For the Federal Reserve the rate is the midpoint of the target range (for example `3.875` for a 3.75 to 4.00 percent range). 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 | Coverage | Updated | | - | - | - | | 10 | Newest published day per bank | Same afternoon for the Federal Reserve; weekly for the other banks | ### 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') ``` # Labor Market Data API Source: https://docs.financialdatasets.ai/api/macro/labor/historical GET /macro/labor US labor market history in 24 series: nonfarm payrolls from 1939, the unemployment rate, participation, hourly earnings, JOLTS job openings, hires, and quits, and weekly jobless claims, with the change from the prior period and from a year earlier. ### Overview The Financial Datasets labor market API returns one US labor market series per request: the jobs report (nonfarm payrolls, the unemployment rate, participation, hourly earnings), JOLTS job openings, hires, and quits, and weekly jobless claims, with the change from the prior period and from a year earlier computed for you. It covers 24 series from 1939 to today, updated monthly and weekly. Payrolls start in 1939, the unemployment rate in 1948, and weekly jobless claims in 1967. The data comes directly from authoritative government sources ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. Values are in each series' own units (thousands of persons, percent, dollars per hour, persons); the changes are in the same units, plus a percent change over the 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 | History | Series | Updated | | - | - | - | | 1939 to today | 24 | Monthly and weekly | ### Series Every concept is available seasonally adjusted (`_sa`) and, except the 4-week averages, not seasonally adjusted (`_nsa`). Monthly (`date` is the first day of the month): | Series | What it is | Units | From | | - | - | - | - | | `payrolls_sa`, `payrolls_nsa` | Total nonfarm employment | Thousands of persons | 1939 | | `unemployment_rate_sa`, `unemployment_rate_nsa` | Unemployment rate | Percent | 1948 | | `unemployment_rate_u6_sa`, `unemployment_rate_u6_nsa` | U-6: unemployed, marginally attached, and part time for economic reasons | Percent | 1994 | | `participation_rate_sa`, `participation_rate_nsa` | Labor force participation rate | Percent | 1948 | | `hourly_earnings_sa`, `hourly_earnings_nsa` | Average hourly earnings, all private employees | Dollars per hour | 2006 | | `job_openings_sa`, `job_openings_nsa` | Job openings, total nonfarm | Thousands | 2000 | | `hires_sa`, `hires_nsa` | Hires, total nonfarm | Thousands | 2000 | | `quits_sa`, `quits_nsa` | Quits, total nonfarm | Thousands | 2000 | Weekly (`date` is the week-ending Saturday): | Series | What it is | Units | From | | - | - | - | - | | `initial_claims_sa`, `initial_claims_nsa` | Initial jobless claims | Persons | 1967 | | `initial_claims_4_week_sa` | Initial jobless claims, 4-week moving average | Persons | 1967 | | `continued_claims_sa`, `continued_claims_nsa` | Continued jobless claims | Persons | 1967 | | `continued_claims_4_week_sa` | Continued jobless claims, 4-week moving average | Persons | 1967 | | `insured_unemployment_rate_sa`, `insured_unemployment_rate_nsa` | Insured unemployment rate | Percent | 1971 | You can fetch this list, with each series' frequency and first available date, with a free `GET` request to: [https://api.financialdatasets.ai/macro/labor/series/](https://api.financialdatasets.ai/macro/labor/series/) ### Reading the fields * `date` is the reference period, not the release date: the first day of the month for monthly series (`2026-08-01` is the August 2026 jobs report, published in early September) and the week-ending Saturday for weekly series (`2026-09-19` is the week of September 13 to 19). * `value` is the published figure in the series' units. * `change_prior` is `value` minus the prior period's value: the prior month for monthly series, the prior week for weekly. Same units as `value`. * `change_year` is `value` minus the value one year earlier: the same month a year back, or the week 52 weeks back. Same units as `value`. * `change_year_pct` is `change_year` as a percent of the year-earlier value, rounded to one decimal. It is `null` for series measured in percent (the unemployment, participation, and insured unemployment rates): a rate's change is stated in points, in `change_year`. * A change is `null` when the comparison period was not published. * History is the latest published values. When a past period is revised, the stored value is replaced. The newest week of a weekly series is the advance figure; it is replaced by the final figure when that is published. ### 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`). For a monthly series any day inside a month selects that month; for a weekly series you get every week-ending Saturday inside the window. 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 Labor Market 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 = 'payrolls_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/labor' 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 labor = response.json().get('labor') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "labor": [ { "series": "payrolls_sa", "date": "2026-08-01", "value": 159075, "change_prior": 162, "change_year": 603, "change_year_pct": 0.4 } ] } ``` ### FAQ #### Is `date` the release date? No. `date` is the reference period. For monthly series it is the first day of the month: `2026-08-01` is the August 2026 jobs report, published in early September. For weekly series it is the week-ending Saturday. #### Are revisions included? Yes. History holds the latest published values. When a past period is revised, the stored value is replaced. The newest week of a weekly series is the advance figure, and the final figure replaces it when published. #### Are both seasonally adjusted and unadjusted series available? Yes. Every concept is available seasonally adjusted (`_sa`). Every concept except the 4-week averages is also available not seasonally adjusted (`_nsa`). #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Latest Jobs Report API Source: https://docs.financialdatasets.ai/api/macro/labor/snapshot GET /macro/labor/snapshot The latest print of all 24 US labor market series in one call, including nonfarm payrolls, the unemployment rate, JOLTS job openings, and weekly jobless claims, with the change from the prior period and from a year earlier. ### Overview The Labor Market Snapshot API returns the most recent print of every labor market series we track: the jobs report (nonfarm payrolls, the unemployment rate, participation, hourly earnings), JOLTS job openings, hires, and quits, and weekly jobless claims. That is 24 rows, each with the change from the prior period and from a year earlier computed for you. Monthly series show their latest month and weekly series their latest week. Pass `series` to get one row. We source the data directly from authoritative government sources. The snapshot refreshes within minutes of each monthly release and within the hour of each weekly release. To receive each release without polling, subscribe to the `labor.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 period | 24 | Monthly and weekly | ### Series Monthly: `payrolls`, `unemployment_rate`, `unemployment_rate_u6`, `participation_rate`, `hourly_earnings`, `job_openings`, `hires`, `quits`. Weekly: `initial_claims`, `initial_claims_4_week`, `continued_claims`, `continued_claims_4_week`, `insured_unemployment_rate`. Each is seasonally adjusted (`_sa`) and, except the 4-week averages, not seasonally adjusted (`_nsa`). The full list is one free `GET` request away: [https://api.financialdatasets.ai/macro/labor/series/](https://api.financialdatasets.ai/macro/labor/series/) ### Reading the fields * `date` is the reference period, not the release date: the first day of the month for monthly series, the week-ending Saturday for weekly series. * `value` is the published figure in the series' units (thousands of persons, percent, dollars per hour, persons). * `change_prior` and `change_year` are `value` minus the prior period's value and minus the value one year earlier, in the same units. * `change_year_pct` is the year change as a percent, rounded to one decimal; `null` for series measured in percent, whose change is stated in points. * A change is `null` when the comparison period was not published. The newest week of a weekly series is the advance figure, replaced by the final figure when published. ### 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 24. ### Example ```python Labor Market 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/labor/snapshot' # make API request response = requests.get(url, headers=headers) # parse the latest prints from the response labor = response.json().get('labor') ``` ### Example Response ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "labor": [ { "series": "payrolls_sa", "date": "2026-08-01", "value": 159075, "change_prior": 162, "change_year": 603, "change_year_pct": 0.4 }, { "series": "initial_claims_sa", "date": "2026-09-19", "value": 197000, "change_prior": -1000, "change_year": -22000, "change_year_pct": -10.0 } ] } ``` The live response has one row per series, 24 in total. # Treasury Yield Curve API Source: https://docs.financialdatasets.ai/api/macro/yield-curve/historical GET /macro/yield-curve The daily US Treasury par yield curve since 1990: 14 tenors from 1-month to 30-year, in percent, one row per business day, updated daily. ### Overview The Financial Datasets Treasury yield curve API returns the daily US Treasury par yield curve: one row per business day, with one key for each of 14 tenors from 1-month to 30-year. Values are par yields in percent. It covers 1990 to today, updated daily. The data comes directly from authoritative government sources ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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 } ] } ``` ### FAQ #### Which maturities are included? 14 tenors: 1, 1.5, 2, 3, 4, and 6 months, and 1, 2, 3, 5, 7, 10, 20, and 30 years. #### Why are some tenors null? A tenor is `null` when it was not published on that date. 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. #### How do I get the full history? Pass a `start_date` in 1990 and follow `next_page_url`. Each page holds up to 100 rows, newest first. With no dates, you get the trailing year. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Latest Treasury Yield Curve API Source: https://docs.financialdatasets.ai/api/macro/yield-curve/snapshot GET /macro/yield-curve/snapshot The most recent business day's US Treasury par yield curve: 14 tenors from 1-month to 30-year, updated daily. ### 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 within minutes of each afternoon's posting. 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 } } ``` # Stock News API (Company News) Source: https://docs.financialdatasets.ai/api/news/company api/news/openapi-company.json GET /news Recent news articles about a public company by ticker, with title, source, date, and link: 10,000+ tickers with 2+ years of history, updated within 1 minute. ### Overview The Financial Datasets company news API returns recent news articles about a public company by ticker, with each article's title, source, date, and link. It covers 10,000+ US tickers with 2+ years of history, updated within 1 minute. Articles come from publicly available news feeds and are matched to the company's ticker ([data provenance](/data-provenance)). You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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') ``` ### FAQ #### Where do the news articles come from? From publicly available news feeds. Articles are collected close to the point of publication and matched to company tickers. #### How many articles can I get per request? Up to 10. Set `limit`; the default is 5. #### Can I get market news without a ticker? Yes. Leave out `ticker` to get broad market news. See [Market News](/api/news/market). #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Market News API Source: https://docs.financialdatasets.ai/api/news/market api/news/openapi-market.json GET /news Recent market-moving news on AI, macro, rates, earnings, geopolitics, energy, crypto, and more, with no ticker needed, updated within 1 minute. ### 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') ``` # Stock Price API (Historical OHLCV) Source: https://docs.financialdatasets.ai/api/prices/historical GET /prices Historical end-of-day stock prices (open, high, low, close, and volume) for 15,000+ US tickers, by day, week, month, or year, with 3+ years of history. ### Overview The Financial Datasets stock prices API returns historical end-of-day (EOD) prices for a stock ticker: open, high, low, close, and volume (OHLCV), by day, week, month, or year. It covers 15,000+ US tickers with 3+ years of history, updated at the end of each day. The prices come from Databento, our market data partner ([data provenance](/data-provenance)). For the latest price, use the [price snapshot](/api/prices/snapshot) endpoint. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. 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" }, ... ] } ``` ### FAQ #### How far back do the prices go? 3+ years. #### Which intervals are available? `day`, `week`, `month`, and `year`. Set `interval` together with `start_date` and `end_date`. #### Where does the price data come from? From Databento, our market data partner. Databento delivers real-time and historical market data direct from colocation sites. #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # US Market Snapshot API Source: https://docs.financialdatasets.ai/api/prices/market-snapshot GET /prices/snapshot/market The latest price, day change, and day change percent of every actively traded US stock in one request: 13,000+ tickers, updated in real time. ### 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 }, ... ] } ``` # Real-Time Stock Price API Source: https://docs.financialdatasets.ai/api/prices/snapshot GET /prices/snapshot The latest price of a US stock, with its day change and day change percent, for 13,000+ tickers, updated in real time. ### 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, consumer prices, and the labor market, 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). # Get US 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 # France Fundamentals in Python Source: https://docs.financialdatasets.ai/guides/get-france-fundamentals-python Income statements, balance sheets, cash flow statements, and financial metrics for 376 French-listed companies, annual, in the reporting currency (EUR for most), with a Python walk-through. The Financial Datasets API serves annual fundamentals for 376 French-listed companies, active and delisted, including the CAC 40: income statements, balance sheets, cash flow statements, financial metrics, and as-reported statements. The data comes from the tagged annual reports French companies file. Amounts are in the currency the company reports in, EUR for most. Financial metrics carry no price-based values (market cap, valuation ratios) yet. See [market coverage](/market-coverage) for every market. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. French fundamentals use the same endpoints as US fundamentals. The only difference is how you name the company: a French ticker together with `market=FR`, or the company's ISIN. This guide walks through both. ## 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: Find a French Ticker Every financials endpoint has a `/tickers/` list. Filter it by `market=FR` to see the French companies we cover, each with its name, ISIN, and whether it is still listed. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = "https://api.financialdatasets.ai/financials/income-statements/tickers/?market=FR" response = requests.get(url, headers=headers) listings = response.json().get("listings") for listing in listings[:5]: print(f"{listing['ticker']}: {listing['name']} ({listing['identifier']}, {listing['status']})") ``` ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "resource": "income-statements", "listings": [ {"ticker": "AI", "name": "L'AIR LIQUIDE", "market": "FR", "identifier": "FR0000120073", "identifier_type": "ISIN", "status": "active"}, {"ticker": "MC", "name": "LVMH MOET HENNESSY-LOUIS VUITTON", "market": "FR", "identifier": "FR0000121014", "identifier_type": "ISIN", "status": "active"} ], "tickers": ["74SW", "AAA", "AB", "..."] } ``` French tickers are the short symbols the Paris market prints, so LVMH is `MC` and Air Liquide is `AI`. ## Step 3: Fetch Income Statements Add `market=FR` next to the ticker. French companies report once a year, so use `period=annual`. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ticker = "AI" market = "FR" period = "annual" limit = 5 url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?ticker={ticker}" f"&market={market}" 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']:,} {stmt['currency']}, Net Income={stmt['net_income']:,} {stmt['currency']}") ``` Amounts are in the currency the company reports in. Read it from the `currency` field on each statement: most French companies report in EUR, some in USD (TotalEnergies, for one). ## Step 4: Request by ISIN Instead If you know the ISIN, pass it on its own. No ticker or market is needed. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?isin=FR0000120073" f"&period=annual" f"&limit=5" ) response = requests.get(url, headers=headers) income_statements = response.json().get("income_statements") ``` ## Step 5: Fetch Balance Sheets and Cash Flow Statements The [Balance Sheets API](/api/financials/balance-sheets) and [Cash Flow Statements API](/api/financials/cash-flow-statements) take the same parameters. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} for statement in ["balance-sheets", "cash-flow-statements"]: url = ( f"https://api.financialdatasets.ai/financials/{statement}" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) print(statement, response.json()) ``` To get all three statements in one request, call the [All Financial Statements API](/api/financials/all-financial-statements) with the same parameters. ## Step 6: Fetch Financial Metrics The [Financial Metrics API](/api/financial-metrics/historical) returns margins, growth, and per-share values for each annual period, and the [Snapshot API](/api/financial-metrics/snapshot) the latest period. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financial-metrics" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) financial_metrics = response.json().get("financial_metrics") for metrics in financial_metrics: print(f"{metrics['report_period']}: Gross Margin={metrics['gross_margin']}, Net Margin={metrics['net_margin']}") ``` Price-based values such as market cap, enterprise value, valuation ratios, and dividend yield are not available for French companies yet and come back as `null`. ## Step 7: Fetch As-Reported Statements As-reported statements give you the lines exactly as the company printed them in its annual report, with the company's own labels and subtotals. Add `/as-reported` to any statement endpoint. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/income-statements/as-reported" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit=1" ) response = requests.get(url, headers=headers) statement = response.json().get("income_statements")[0] def print_lines(nodes, depth=0): for node in nodes: print(f"{' ' * depth}{node['label']}: {node['value']}") print_lines(node["children"], depth + 1) print_lines(statement["line_items"]) ``` ## Annual Data Only French companies file one tagged annual report a year, so `period=annual` is the only period. A request with `period=quarterly` or `period=ttm` returns a `400`: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "error": "Invalid period", "message": "FR listings carry annual data only. Use period=annual." } ``` ## Next Steps * [Market Coverage](/market-coverage) — which markets are available and how to request each * [Income Statements API Reference](/api/financials/income-statements) — full parameter documentation * [Financial Metrics API](/api/financial-metrics/historical) — every metric we calculate * [Get US Fundamentals Guide](/guides/analyze-financial-statements-python) — the same walk-through for US companies * [Get UK Fundamentals Guide](/guides/get-uk-fundamentals-python) — the same walk-through for UK companies ## FAQ #### Which French companies are covered? Every French company that files a tagged annual report, active and delisted: 376 companies, including the CAC 40. #### Which periods are available? Annual only. `period=quarterly` and `period=ttm` return a `400`. #### Can I get the statements as the company printed them? Yes. The as-reported endpoints return each line in the company's own order and wording. See [As-Reported Financial Statements](/api/financials/as-reported). #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Pull 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 # UK Fundamentals in Python Source: https://docs.financialdatasets.ai/guides/get-uk-fundamentals-python Income statements, balance sheets, cash flow statements, and financial metrics for 674 UK-listed companies, annual, in the reporting currency, with a Python walk-through. The Financial Datasets API serves annual fundamentals for 674 UK-listed companies, active and delisted, including the FTSE 100: income statements, balance sheets, cash flow statements, financial metrics, and as-reported statements with the lines as the company printed them. The data comes from the tagged annual reports companies file with the UK regulator. Amounts are in the currency the company reports in. Financial metrics carry no price-based values (market cap, valuation ratios) yet. See [market coverage](/market-coverage) for every market. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the [MCP server](/mcp-server), or pay per request with [x402](/x402). [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. UK fundamentals use the same endpoints as US fundamentals. The only difference is how you name the company: a UK ticker together with `market=UK`, or the company's ISIN. This guide walks through both. ## 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: Find a UK Ticker Every financials endpoint has a `/tickers/` list. Filter it by `market=UK` to see the UK companies we cover, each with its name, ISIN, and whether it is still listed. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = "https://api.financialdatasets.ai/financials/income-statements/tickers/?market=UK" response = requests.get(url, headers=headers) listings = response.json().get("listings") for listing in listings[:5]: print(f"{listing['ticker']}: {listing['name']} ({listing['identifier']}, {listing['status']})") ``` ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "resource": "income-statements", "listings": [ {"ticker": "RR.", "name": "ROLLS-ROYCE HOLDINGS PLC", "market": "UK", "identifier": "GB00B63H8491", "identifier_type": "ISIN", "status": "active"}, {"ticker": "SHEL", "name": "SHELL PLC", "market": "UK", "identifier": "GB00BP6MXD84", "identifier_type": "ISIN", "status": "active"} ], "tickers": ["AAL", "ABF", "ADM", "..."] } ``` UK tickers keep the spelling their exchange prints, so a ticker like `RR.` includes the trailing dot. ## Step 3: Fetch Income Statements Add `market=UK` next to the ticker. UK companies report once a year, so use `period=annual`. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} ticker = "RR." market = "UK" period = "annual" limit = 5 url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?ticker={ticker}" f"&market={market}" 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']:,} {stmt['currency']}, Net Income={stmt['net_income']:,} {stmt['currency']}") ``` Older code that sends `exchange=LSE` keeps working: it means `market=UK`. Amounts are in the currency the company reports in. Read it from the `currency` field on each statement: most UK companies report in GBP, some in USD or EUR. ## Step 4: Request by ISIN Instead If you know the ISIN, pass it on its own. No ticker or market is needed. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/income-statements" f"?isin=GB00B63H8491" f"&period=annual" f"&limit=5" ) response = requests.get(url, headers=headers) income_statements = response.json().get("income_statements") ``` ## Step 5: Fetch Balance Sheets and Cash Flow Statements The [Balance Sheets API](/api/financials/balance-sheets) and [Cash Flow Statements API](/api/financials/cash-flow-statements) take the same parameters. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} for statement in ["balance-sheets", "cash-flow-statements"]: url = ( f"https://api.financialdatasets.ai/financials/{statement}" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) print(statement, response.json()) ``` To get all three statements in one request, call the [All Financial Statements API](/api/financials/all-financial-statements) with the same parameters. ## Step 6: Fetch Financial Metrics The [Financial Metrics API](/api/financial-metrics/historical) returns margins, growth, and per-share values for each annual period, and the [Snapshot API](/api/financial-metrics/snapshot) the latest period. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financial-metrics" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit={limit}" ) response = requests.get(url, headers=headers) financial_metrics = response.json().get("financial_metrics") for metrics in financial_metrics: print(f"{metrics['report_period']}: Gross Margin={metrics['gross_margin']}, Net Margin={metrics['net_margin']}") ``` Price-based values such as market cap, enterprise value, valuation ratios, and dividend yield are not available for UK companies yet and come back as `null`. ## Step 7: Fetch As-Reported Statements As-reported statements give you the lines exactly as the company printed them in its annual report, with the company's own labels and subtotals. Add `/as-reported` to any statement endpoint. ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} url = ( f"https://api.financialdatasets.ai/financials/income-statements/as-reported" f"?ticker={ticker}" f"&market={market}" f"&period={period}" f"&limit=1" ) response = requests.get(url, headers=headers) statement = response.json().get("income_statements")[0] def print_lines(nodes, depth=0): for node in nodes: print(f"{' ' * depth}{node['label']}: {node['value']}") print_lines(node["children"], depth + 1) print_lines(statement["line_items"]) ``` ## Annual Data Only UK companies file one tagged annual report a year, so `period=annual` is the only period. A request with `period=quarterly` or `period=ttm` returns a `400`: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "error": "Invalid period", "message": "UK listings carry annual data only. Use period=annual." } ``` ## Next Steps * [Market Coverage](/market-coverage) — which markets are available and how to request each * [Income Statements API Reference](/api/financials/income-statements) — full parameter documentation * [Financial Metrics API](/api/financial-metrics/historical) — every metric we calculate * [Get US Fundamentals Guide](/guides/analyze-financial-statements-python) — the same walk-through for US companies * [UK fundamentals announcement](https://www.financialdatasets.ai/news/uk-fundamentals) — what launched and which companies are covered ## FAQ #### Which UK companies are covered? Every company that files a tagged annual report with the UK regulator, active and delisted: 674 companies, including the FTSE 100. #### Which periods are available? Annual only. UK companies file one tagged annual report a year, so `period=quarterly` and `period=ttm` return a `400`. #### Can I get the statements as the company printed them? Yes. The as-reported endpoints return each line in the company's own order and wording. See [As-Reported Financial Statements](/api/financials/as-reported). #### Can an AI agent use this data? Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the [Financial Datasets MCP server](/mcp-server). An agent with a wallet can also pay per request with [x402](/x402), with no account. # Understanding 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, inflation, and the labor market. Endpoints that return a single object — company facts, snapshots, interest rates — and `/filings/items` (the sections of one filing) always return their full result. # 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 # 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. > [!NOTE] > > **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. > [!NOTE] > > 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`. > [tab] Python (Flask) > > 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 > ``` > [tab] Node (Express) > > 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. > [!WARNING] > > 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. > [card] [REST API](/quickstart) > > Authenticate and make your first request in under two minutes. > [card] [MCP Server](/mcp-server) > > Give Claude, ChatGPT, Hermes, and other agents direct access to market data. > [card] [Webhooks](/webhooks) > > Get pushed the moment filings, earnings, or insider events hit. > [card] [x402](/x402) > > No API key, no account. Your agent pays per request in USDC. ## 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, the labor market, 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 Public company financials for 27,000+ tickers over 30+ years. | Market | Status | Request with | Periods | Currency | | - | - | - | - | - | | United States | Available | `ticker` or `cik` | Annual, quarterly, TTM | USD | | United Kingdom | Available | `ticker` + `market=UK`, or `isin` | Annual | As reported | | France | Available | `ticker` + `market=FR`, or `isin` | Annual | As reported | | India | Coming soon | | | | | EU (more markets) | Coming soon | | | | | Japan | Coming soon | | | | | South Korea | Coming soon | | | | * **United States** covers every SEC filer, active and delisted. Also has segments, as-reported statements, earnings, and KPIs. * **United Kingdom** covers every company that files a tagged annual report with the UK regulator, active and delisted: 674 companies, including the FTSE 100 ([announcement](https://www.financialdatasets.ai/news/uk-fundamentals)). Also has as-reported statements, the lines as the company printed them. Financial metrics carry no price-based values (market cap, enterprise value, valuation ratios, dividend yield) yet. * **France** covers every French company that files a tagged annual report, active and delisted: 376 companies, including the CAC 40. Also has as-reported statements. Amounts are in the currency the company reports in, EUR for most. Financial metrics carry no price-based values yet, as for the UK. ## Discovering Available Tickers To see which tickers are available for a given dataset, append `/tickers` to any endpoint: ``` # Every market GET https://api.financialdatasets.ai/financials/tickers/ # One market GET https://api.financialdatasets.ai/financials/tickers/?market=UK GET https://api.financialdatasets.ai/financials/tickers/?market=FR ``` The financials and financial metrics endpoints return two lists: `listings`, one entry per listed ticker with its name, market, identifier (a CIK for US listings, an ISIN for UK and French listings, named by `identifier_type`) and status (`active` or `delisted`), and `tickers`, the flat list of US tickers (or of the market named by `market`). ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "resource": "financials", "listings": [ {"ticker": "AAPL", "name": "Apple Inc.", "market": "US", "identifier": "0000320193", "identifier_type": "CIK", "status": "active"}, {"ticker": "SHEL", "name": "Shell plc", "market": "UK", "identifier": "GB00BP6MXD84", "identifier_type": "ISIN", "status": "active"}, {"ticker": "AI", "name": "Air Liquide", "market": "FR", "identifier": "FR0000120073", "identifier_type": "ISIN", "status": "active"} ], "tickers": ["A", "AA", "AAPL", "..."] } ``` Requests that still send `exchange=LSE` keep working: it means `market=UK`. France has no such alias: name it with `market=FR`. Visit the APIs section of this documentation for full endpoint references, query parameters, and coverage. # Financial Data MCP Server Source: https://docs.financialdatasets.ai/mcp-server The official Financial Datasets MCP server for Claude, ChatGPT, Gemini, Cursor, and more: stock prices, financial statements, SEC filings, insider trades, and 13F holdings. ## Overview The official Financial Datasets MCP server connects AI assistants to stock prices, financial statements, SEC filings, insider trades, institutional holdings, earnings, and news. It works with Claude, ChatGPT, Gemini, Grok, Cursor, and other clients that support remote MCP servers. Interactive clients sign you in, so you need no API key. Scripts and production agents connect to `https://mcp.financialdatasets.ai/api` with an API key. ## Connect your client Pick your client and follow the steps. Interactive clients sign you in automatically — no API key needed. > [tab] Claude > > Install the official **Financial Datasets** connector from Claude's Connectors Directory. Works for both **Claude.ai** (web) and the **Claude Desktop** app. > > 1. Open [Financial Datasets in Claude](https://claude.ai/directory/financial-datasets), or search for **Financial Datasets** in **Customize** → **Connectors** > 2. Click **Connect** and complete sign-in > 3. In any new chat, click **+** and enable **Financial Datasets** under Connectors > > ### Claude Code > > 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`. > [tab] ChatGPT > > Install the official **Financial Datasets** plugin from ChatGPT's Plugin Directory. > > 1. Open [Financial Datasets in ChatGPT](https://chatgpt.com/plugins/financial-datasets), 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** > > ### Codex > > 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 connector is then available in the Codex app, CLI, and IDE extension. Verify anytime with `codex mcp list` or type `/mcp` in Codex. > [tab] Gemini > > Add Financial Datasets as a custom app in the **Gemini web app**. Custom apps need a personal Google Account (18 or over, in the US) with **Keep Activity** turned on. > > 1. On your computer, go to [gemini.google.com](https://gemini.google.com) > 2. At the bottom, click **Settings** → **Connected Apps**. If you don't see it, first click **Personal Intelligence** → **Connected Apps** > 3. Under **Custom apps**, find the **Add a custom app link to get started** field, or click **Add a custom app** if you already connected one > 4. Enter the MCP connector URL: > > ``` > https://mcp.financialdatasets.ai/ > ``` > > 5. Click **Next**, then follow the on-screen instructions to complete sign-in > 6. In a chat, enter `@` and select the app to make sure Gemini uses it for your prompt > > See Google's [custom apps help page](https://support.google.com/gemini/answer/17209137) for managing or disconnecting the app. > [tab] Grok > > Add Financial Datasets as a custom connector in **Grok**. > > 1. Go to [grok.com/connectors](https://grok.com/connectors) > 2. Click **New Connector**, then select **Custom** > 3. Enter the MCP connector URL and complete sign-in: > > ``` > https://mcp.financialdatasets.ai/ > ``` > > On **Grok Business** and **Enterprise** plans, a team admin adds it instead: on the connectors page, click **+ Add Connector**, select **Other**, and enter the same URL. > > See xAI's [connectors docs](https://docs.x.ai/grok/connectors) for details. > [tab] Hermes > > Add the connector 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. > [tab] OpenClaw > > Add the Financial Datasets MCP connector 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. > [tab] Cursor > > 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/)). > [tab] Python > > 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 connector > 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()) > ``` > [tab] Claude Managed Agents > > 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 > [accordion] Browse all 20+ 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. > > **Macro Data** > > * **`get_macro_data`**: Get macroeconomic datasets. `dataset=yield_curve` returns the daily US Treasury par yield curve, `dataset=interest_rates` returns central bank policy rates (current snapshot, or one bank's history via `bank`), `dataset=inflation` returns US CPI series, and `dataset=labor` returns US labor market series (payrolls, unemployment, earnings, job openings, weekly jobless claims). Omit the dates for the latest values, or pass `start_date` / `end_date` for history. > > **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?" ## FAQ #### Is this the official Financial Datasets MCP server? Yes. Financial Datasets builds and runs it at `https://mcp.financialdatasets.ai`. It is listed in Claude's Connectors Directory and in ChatGPT's Plugin Directory. #### Do I need an API key? Not for Claude, ChatGPT, and other interactive clients: they sign you in. Scripts and production agents use an API key with the `/api` endpoint. #### What does it cost? The same as the API. [Pricing](https://www.financialdatasets.ai/pricing) starts at \$20. # 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: > [card] [openapi.json](https://financialdatasets.ai/openapi.json) > > [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: > [accordion] Get the latest stock price > > ```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']}") > ``` > [accordion] Look up company info > > ```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']}") > ``` > [accordion] Check insider trades > > ```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']}") > ``` > [accordion] Search for high-revenue companies > > ```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? > [card] [Financial Statements](/api/financials/income-statements) > > Income statements, balance sheets, and cash flow statements. > [card] [Stock Prices](/api/prices/historical) > > Historical and real-time price data. > [card] [SEC Filings](/api/filings/ticker) > > 10-K, 10-Q, 8-K filings with section-level extraction. > [card] [MCP Server](/mcp-server) > > Connect your AI assistant directly to our data. # Best Practices Source: https://docs.financialdatasets.ai/search/best-practices Get better answers from Search: write precise queries, improve one change at a time, and use the request shape for each kind of task. ## Be precise The more precise the query, the better the answer. A vague query finds the general area. A specific one finds the passage you want. Describe what you want, and include every detail that changes which passage is right: the subject, the people, the period, the kind of thing (a policy, a table, a number). Write it as a description or as a question; both work. Length is not the goal. Add the words that change the answer, and leave out the words that only describe your task. The same request for one company, made clearer one step at a time: | Query | What comes back | | - | - | | `retainers` | A passage about director pay in general. | | `director pay` | The director pay table as a whole. | | `annual cash retainers paid to directors for committee service` | The retainer for each committee, chair and member. | | the same with `filters.date` for 2025 | The same amounts, from the document the company filed in 2025. | ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "query": "annual cash retainers paid to directors for committee service", "filters": { "identifiers": { "ticker": ["CCI"] }, "date": { "after": "2025-01-01", "before": "2025-12-31" } } } ``` ## The fields | Field | What it does | | - | - | | `query` | Says clearly what you want. The only required field, at most 300 characters. | | `filters.identifiers` | Names the companies. Send it whenever you know them; without it every company's newest document is searched. | | `filters.date` | Bounds the day the document became public. Send it for a period or one year. | | `filters.document_type` | Names the kinds of document to read: `DEF 14A` for a proxy statement, `8-K` for a current report. Send it when a passage from the other kind would be wrong; without it the kinds the question names are read, and every kind when it names none. | | `limit` | How many documents come back: 10 unless you say otherwise, up to 100. | ## Improve a result one change at a time Change one thing, compare, then change the next. Two changes at once hide which one helped. **1. Add the detail that is missing** When the answer is close but not right, the query is missing a detail that would decide it: the people, the period, the kind of thing. `executive pay` becomes `total compensation of each named executive officer for 2025`. **2. Read the title, the date and the section** `title` says which document answered, `date` which year, and `citation.section` where in the document the passage sits. The right section with a weak excerpt calls for a more specific query. The wrong document calls for a filter. **3. Use the company's own word** Companies name the same practice differently: clawback and recoupment, special committee and ad hoc committee, relative TSR and rTSR. When a query returns nothing useful, send the other name as a second request. **4. Add a filter only to exclude** A filter is a constraint, not a preference. Send `filters.identifiers`, `filters.date` or `filters.document_type` when a passage from outside it would be wrong. A preference for a company, a year or a kind of document goes in the query text. **5. Raise the limit last** More documents do not make the first ones better. Raise `limit` when the task needs more documents, not to find a passage the query missed. ## Request shapes by task | You want | Send | Avoid | | - | - | - | | One fact from one company | A description of the fact with the people and the year, the ticker in `filters.identifiers`. | A one-word topic. | | A whole table | The table's name as the topic. The excerpt carries `attributes.kind` of `table` and holds every row. | Asking for one cell and reading the rest through the link. | | What a company announced: its results, a new officer, a departure, an agreement | The announcement with the ticker, `filters.document_type` of `["8-K"]`, and `filters.date` around the event. | No window; every current report of the company is then in scope. | | How a company is governed or pays its people | The topic with the ticker and `filters.document_type` of `["DEF 14A"]`. | A year in the query text. | | What a company says today | The topic and the ticker, no window. | A year in the query text; it widens the search to every year. | | A period, or one year | `filters.date` with `after`, `before`, or both. | A year in the query text. | | The same question over a set of companies | Up to 20 tickers in `filters.identifiers` and `limit` of 100. Beyond 20, batches of 20. | One request that lists hundreds of tickers. | | Yes or no for each company in a set | One request per company; read the excerpt before you decide. | Counting results. A result is the nearest passage, not a yes, and an absent company is not a no. | | A practice with several names | One request per name. | One query that lists every name. | ## When a model writes the queries An agent that calls Search writes vague queries unless its tool definition says otherwise. Put the rules in the parameter descriptions, make the identifiers required, and have it make one call per item. ```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} query: A clear, specific description of what you want, with every detail that changes the answer: the subject, the people, the period, the kind of thing. A question is fine. Never a single loose word, and never a description of the overall task. identifiers: The tickers or CIKs of the companies the question is about. Required whenever the company is known. date: An after day and a before day. Send it only when the question is about a period or one year, and always for an announcement. document_type: The kinds of document to read: "DEF 14A" for how a company is governed or pays its people, "8-K" for what it announced. Send it when a passage from the other kind would be wrong. ``` Have the agent read `warnings` before it concludes. `no_documents` means there was nothing to search for those companies in that window, not that the answer is no. ## Quote the excerpt, cite the link `text` is the passage as written in the document and may be quoted as such. `citation.link` opens the document at the passage, highlighted. Keep `citation.document`, `citation.date` and `citation.section` with the quotation: together they identify the document, its date and the place in it. ## Keep a reference set of queries Record about ten queries that stand for the real work. Run them all after every change to a prompt or a tool definition, so a gain on one query is not paid for by three others. Store each response's `search_id` with its query. When a passage is wrong or missing, the id lets us reproduce the case exactly. ## Common mistakes | Mistake | Do this instead | | - | - | | A one- or two-word topic | A precise description of what you want, with the details that change the answer. | | No ticker when the company is known | Send it in `filters.identifiers`. | | The whole task in one query | One short query per item. `query` takes at most 300 characters. | | A year in the query to mean that year only | `filters.date` for the year. | | An announcement asked with no window | `filters.date` around the event, with `filters.document_type` of `["8-K"]`. | | Retrying a `422` | Send `filters.identifiers` with the company; the same query then succeeds. Retry only a `503`. | | Judging by the excerpt alone | Read `title`, `date` and `citation.section` too. They say whether the query or a filter should change. | ## When another endpoint fits > [card] [Filings](/api/filings/ticker) > > The list of a company's filings, or a whole filing and its items, rather than the part that answers a question. # Search Source: https://docs.financialdatasets.ai/search/introduction POST /search Ask a question about a public company in plain English and get the answer from what it reported, with a citation. Search answers a question about a public company from what the company has reported, and shows where the answer came from: how it pays its directors, what its clawback policy says, what it announced in its latest results release, who replaced its chief financial officer. You send a precise query and the companies you mean. You get back the parts of the record that answer it, word for word, each with a link that opens the source at that place. > [!NOTE] > > **Alpha.** Access is by invitation; callers without access receive a `404`. The request and response shapes may change during the alpha. Contact us to request access. ## Make your first request Search uses the same API key as every other endpoint. ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} import requests response = requests.post( "https://api.financialdatasets.ai/search", headers={"X-API-KEY": "your_api_key_here"}, json={ "query": "committee retainers", "filters": {"identifiers": {"ticker": ["CCI"]}}, }, ) for result in response.json()["results"]: print(result["title"], result["url"]) for excerpt in result["excerpts"]: print(excerpt["text"], excerpt["citation"]["link"]) ``` ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} const response = await fetch("https://api.financialdatasets.ai/search", { method: "POST", headers: { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" }, body: JSON.stringify({ query: "committee retainers", filters: { identifiers: { ticker: ["CCI"] } }, }), }); const { results } = await response.json(); for (const result of results) { console.log(result.title, result.url); for (const excerpt of result.excerpts) { console.log(excerpt.text, excerpt.citation.link); } } ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl -s -X POST "https://api.financialdatasets.ai/search" \ -H "Content-Type: application/json" \ -H "X-API-KEY: $FINANCIAL_DATASETS_API_KEY" \ -d '{ "query": "committee retainers", "filters": { "identifiers": { "ticker": ["CCI"] } } }' ``` Each result is one document. Each excerpt is a passage from that document, reproduced verbatim, with a link that opens the document at the passage. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "title": "Crown Castle Inc · DEF 14A 2026", "url": "https://www.sec.gov/Archives/edgar/data/1051470/000105147026000039/cci-20260406.htm", "date": "2026-04-06", "excerpts": [ { "text": "2025 Committee Retainers(a)\nBoard Committee | Committee Chair | Committee Member(b)\nAudit Committee | $30,000 | $15,000\nCEO Search Committee | $20,000 | $10,000\nCHC Committee | $25,000 | $12,500\nFiber Review Committee | $25,000 | $12,500 ...", "citation": { "document": "0001051470-26-000039", "date": "2026-04-06", "section": "Crown Castle Inc. > 2025 Committee Retainers(a)", "link": "https://www.sec.gov/Archives/edgar/data/1051470/000105147026000039/cci-20260406.htm#:~:text=Committee%20Member%28b%29,N%26G%20Committee" }, "attributes": { "kind": "table" } } ] } ``` ## Write the query `query` is the only required field, at most 300 characters. The more precise the query, the better the answer. Five rules cover most requests. | Rule | Example | | - | - | | Say clearly what you want. Include every detail that changes the answer: the subject, the people, the period, the kind of thing. | `annual cash retainers paid to directors for committee service`, not `retainers`. | | Write a description or a question; both work. A vague query fails in either form. | `How much does Crown Castle pay directors who serve on board committees?` works. `What about pay?` does not. | | Name the fact when you want a value. Name the table or section when you want the whole of it. | `total compensation of each named executive officer for 2025` returns the rows that hold the values. `summary compensation table` returns the table. | | Send one query per item you want. | `clawback policy` and `stock ownership guidelines` as two requests, not one. | | Put the company in `filters.identifiers`. | `committee retainers` with `{"ticker": ["CCI"]}`. The company may also be named in the text, as in `committee retainers for CCI`. | A year in the query text widens the search to every year on record. To search one year, send `filters.date` instead. ## Name the companies `filters.identifiers` lists the companies to search, by `ticker` or `cik`. A CIK may be sent without leading zeros. A list runs the same query over each company in it. An identifier that matches no listed company is a `400` that names it. Send it whenever you know the company. Without it, Search reads the newest document of every company. A query that names a company Search cannot identify is a `422` with the fix in the body, never an answer drawn from other companies' documents. ## Pick the kind of document Search reads two kinds of document today. A proxy statement (`DEF 14A`) says how a company is governed and how it pays its directors and executives. A current report (`8-K`) says what a company announced: its results, a new officer, a departure, an agreement. A current report often carries the announcement itself as an exhibit, such as the results press release. `filters.document_type` names the kinds to read, as a result's `attributes.document_type` names them: `["DEF 14A"]`, `["8-K"]`, or both. Send it when a passage from the other kind would be wrong. Without it, Search reads the kinds the question names, and every kind when the question names none: `clawback policy` reads the proxy statements; `press release on quarterly results` reads the current reports. ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} response = requests.post( "https://api.financialdatasets.ai/search", headers={"X-API-KEY": "your_api_key_here"}, json={ "query": "quarterly revenue and net income announced in the results press release", "filters": { "identifiers": {"ticker": ["AAPL"]}, "document_type": ["8-K"], "date": {"after": "2026-07-01", "before": "2026-08-31"}, }, "limit": 1, }, ) ``` ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} const response = await fetch("https://api.financialdatasets.ai/search", { method: "POST", headers: { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" }, body: JSON.stringify({ query: "quarterly revenue and net income announced in the results press release", filters: { identifiers: { ticker: ["AAPL"] }, document_type: ["8-K"], date: { after: "2026-07-01", before: "2026-08-31" }, }, limit: 1, }), }); ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl -s -X POST "https://api.financialdatasets.ai/search" \ -H "Content-Type: application/json" \ -H "X-API-KEY: $FINANCIAL_DATASETS_API_KEY" \ -d '{ "query": "quarterly revenue and net income announced in the results press release", "filters": { "identifiers": { "ticker": ["AAPL"] }, "document_type": ["8-K"], "date": { "after": "2026-07-01", "before": "2026-08-31" } }, "limit": 1 }' ``` The result is the press release, an exhibit of the current report. Its `title` names the exhibit, and its `attributes` carry the exhibit and the items the report covers. The excerpt is shortened. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "title": "Apple Inc · 8-K 2026-07-30 · EX-99.1", "url": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000018/a8-kex991q3202606272026.htm", "date": "2026-07-30", "source": "sec.gov", "excerpts": [ { "text": "Exhibit 99.1\nApple reports third quarter results\nJune quarter records for total company revenue and EPS\niPhone, Mac and Services revenue set new June quarter records\nCUPERTINO, CALIFORNIA — Apple today announced financial results for its fiscal 2026 third quarter ended June 27, 2026. The Company posted quarterly revenue of $109.4 billion, up 16 percent year over year. ...", "citation": { "document": "0000320193-26-000018-2", "date": "2026-07-30", "section": "Apple reports third quarter results > iPhone, Mac and Services revenue set new June quarter records", "link": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000018/a8-kex991q3202606272026.htm#:~:text=Apple%20reports%20third,meeting%20of%20shareholders." }, "attributes": { "kind": "text" } } ], "entities": [ { "name": "Apple Inc", "identifiers": { "cik": "0000320193", "ticker": "AAPL" } } ], "attributes": { "document_type": "8-K", "exhibit": "EX-99.1", "items": ["2.02", "9.01"] } } ``` ## Set the window `filters.date` bounds the day a document became public: `after`, `before`, or both, as ISO days. Both bounds are inclusive. When you send no window and the query names no year, only the newest proxy statement of each company is searched; a company files one a year. Current reports are many a year, so every one of them stays in scope: send `filters.date` around the event you mean. A window keeps every document inside it in scope. "Every document since 2024" is `{"after": "2024-01-01"}`; one year is both bounds. ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} response = requests.post( "https://api.financialdatasets.ai/search", headers={"X-API-KEY": "your_api_key_here"}, json={ "query": "director attendance below 75% of board and committee meetings", "filters": { "identifiers": {"ticker": ["JPM", "BAC", "C", "WFC"]}, "date": {"after": "2024-01-01"}, }, "limit": 25, }, ) ``` ```javascript JavaScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} const response = await fetch("https://api.financialdatasets.ai/search", { method: "POST", headers: { "X-API-KEY": "your_api_key_here", "Content-Type": "application/json" }, body: JSON.stringify({ query: "director attendance below 75% of board and committee meetings", filters: { identifiers: { ticker: ["JPM", "BAC", "C", "WFC"] }, date: { after: "2024-01-01" }, }, limit: 25, }), }); ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} curl -s -X POST "https://api.financialdatasets.ai/search" \ -H "Content-Type: application/json" \ -H "X-API-KEY: $FINANCIAL_DATASETS_API_KEY" \ -d '{ "query": "director attendance below 75% of board and committee meetings", "filters": { "identifiers": { "ticker": ["JPM", "BAC", "C", "WFC"] }, "date": { "after": "2024-01-01" } }, "limit": 25 }' ``` ## Read the response One result per document, best first. Ten documents come back unless `limit` says otherwise; the most you can ask for is 100. A key that does not apply to a result is absent, never `null`. **Example response** for `clawback policy for incentive compensation` with `filters.identifiers.ticker` of `["AAPL"]`. The excerpts are shortened. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "search_id": "48805604-29b5-431f-ae85-7a405d576984", "results": [ { "title": "Apple Inc · DEF 14A 2026", "url": "https://www.sec.gov/Archives/edgar/data/320193/000130817926000008/aapl014016-def14a.htm", "date": "2026-01-08", "source": "sec.gov", "excerpts": [ { "text": "Recoupment of Compensation\nThe terms of all outstanding time-based and performance-based RSU awards held by our named executive officers in 2025 allow us to recoup any shares or other ...", "citation": { "document": "0001308179-26-000008", "date": "2026-01-08", "section": "Compensation > Compensation Discussion and Analysis > Governance and Other Considerations > Recoupment of Compensation", "link": "https://www.sec.gov/Archives/edgar/data/320193/000130817926000008/aapl014016-def14a.htm#:~:text=Governance%20and%20Other,to%20limited%20exceptions." }, "attributes": { "kind": "text" } }, { "text": "Executive Compensation Policies and Practices\nWe are committed to sound executive compensation policies and practices, as highlighted in the following table.\nProhibition on hedging, pledging, and short sales | ...", "citation": { "document": "0001308179-26-000008", "date": "2026-01-08", "section": "Compensation > Compensation Discussion and Analysis > Executive Compensation Policies and Practices", "link": "https://www.sec.gov/Archives/edgar/data/320193/000130817926000008/aapl014016-def14a.htm#:~:text=We%20have%20robust%20stock%20ownership%20guidelines,annual%20risk%20assessment%20of%20our%20compensation%20program." }, "attributes": { "kind": "table" } } ], "entities": [ { "name": "Apple Inc", "identifiers": { "cik": "0000320193", "ticker": "AAPL" } } ], "attributes": { "document_type": "DEF 14A" } } ] } ``` | Field | Meaning | | - | - | | `search_id` | The id of this search. Keep it when you report a result to us. | | `results[]` | One document each: `title`, `url`, `date`, `source`, `excerpts`, `entities`, `attributes`. | | `excerpts[]` | The parts of the document that answer, verbatim, best first, at most 10. Each has its own `citation` and `attributes`. | | `citation` | `document` is the document's id at its source, `date` the day it became public, `section` the location of the passage within the document, and `link` opens the document at the passage, highlighted. | | `attributes.kind` | `text` or `table`. A table passage is the whole table, rows on lines and cells separated by `\|`. | | `entities[]` | The companies the result is about, with their `cik` and `ticker`. | | `attributes` | What is true of the document: `document_type` always; `exhibit` when the document is an exhibit of a filing, for example `EX-99.1`; `items` for a current report, the codes of the events it reports, for example `["2.02", "9.01"]`. | | `warnings[]` | What a partial answer is missing, each `{type, message, hint}`. Present only when something is. `no_documents` means Search holds no document for these companies in this window; its `hint` names the dates it does hold. Widen the window or check the identifiers before you conclude. | ## Errors | Status | When | Body | | - | - | - | | `400` | The body is not valid. | `error.message` names the field, for example `limit: Input should be less than or equal to 100` or `filters.document_type.0: Input should be 'DEF 14A' or '8-K'`. | | `404` | The caller does not have access during the alpha. | `{"error": "The endpoint /search does not exist."}` | | `422` | The query names a company Search cannot identify. | `error.reason` is `ambiguous_symbol` or `unresolved_company`; `error.hint` says what to send. | | `503` | Search is temporarily unavailable. | `error.message`. Try again shortly. | ## Next steps > [card] [Best Practices](/search/best-practices) > > Write precise queries, improve one change at a time, and use the request shape for each kind of task. # 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. > [!NOTE] > > **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. > [!NOTE] > > 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: **1. Create a destination** Register an HTTPS endpoint and the events you want to receive from the [Webhooks dashboard](https://financialdatasets.ai/webhooks). **2. Set up your endpoint** 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. **3. Verify the signature** Confirm each request came from us using the `FD-Signature` header. See [Verifying the signature](#verifying-the-signature). **4. Test with a canned event** Fire a test event from the dashboard's destination row and confirm your endpoint returns `2xx` within 10 seconds. **5. Go live** 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`, `labor.created`, `interest_rates.created` | Within minutes of each afternoon's Treasury yield curve posting; within minutes of each monthly consumer price, PCE price index, jobs report, and job openings release; within the hour of each weekly jobless claims release; a Federal Reserve rate decision the same afternoon it is announced; the other central banks once the weekly daily-rate series carrying the change is published. | > [card] [Webhook event types](/webhooks/events) > > 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. > [!WARNING] > > 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. > [tab] Python > > ```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) > ``` > [tab] Node > > ```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. > [!WARNING] > > **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). ## 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. > [!NOTE] > > **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 four 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, the newest reference period of the release for the labor market, the first day a new policy rate is in effect for interest rates. | | `release` | string | Inflation: `cpi` or `pce`. Labor market: `jobs_report`, `job_openings`, or `jobless_claims`. | | `bank` | string | Interest rates only: the central bank code, e.g. `FED`. | | *dataset key* | object \| array | Identical to the body of the corresponding snapshot response: `yield_curve` is one object, `inflation`, `labor`, and `interest_rates` are arrays with one entry per series (one entry, the bank's row, for interest rates). | One event per dataset per new date (per release for inflation and the labor market, per bank per rate change for interest rates). 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" } } } } ``` > [!WARNING] > > **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. > [!NOTE] > > **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 inflation data is published, within minutes of the release. One event per release per reference month: the consumer price index (`cpi`, published in the middle of the following month) and the PCE price index (`pce`, about two weeks later). The `release` field names which one. Shape: [print-level](#print-level), carrying `inflation` plus `release`. The array is the matching slice of [`GET /macro/inflation/snapshot`](/api/macro/inflation/snapshot): one entry per series in the release, 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", "release": "cpi", "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 every series in the release: twelve for `cpi`, two for `pce` (`pce_all_sa`, `pce_core_sa`, index 2017 = 100). `date` is the reference month as its first day, not the release date, the same convention the Inflation API uses. ### `labor.created` Fires when a new labor market release is published, within minutes of the monthly releases and within the hour of the weekly claims release. One event per release: the monthly jobs report (`jobs_report`: payrolls, the unemployment rates, participation, hourly earnings), the monthly job openings report (`job_openings`: job openings, hires, quits), and the weekly jobless claims release (`jobless_claims`: initial and continued claims, their 4-week averages, the insured unemployment rates). The `release` field names which one. Shape: [print-level](#print-level), carrying `labor` plus `release`. The array is the matching slice of [`GET /macro/labor/snapshot`](/api/macro/labor/snapshot): one entry per series in the release, each with the value, the change from the prior period, the change from a year earlier, and that change as a percent. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "d8f3b0a5-2c4e-4f60-9b7c-0d1e2f3a4b5c", "type": "labor.created", "api_version": "2026-05-20", "livemode": true, "created": 1788600000, "data": { "object": { "date": "2026-08-01", "release": "jobs_report", "labor": [ { "series": "payrolls_sa", "date": "2026-08-01", "value": 159075, "change_prior": 162, "change_year": 603, "change_year_pct": 0.4 }, { "series": "unemployment_rate_sa", "date": "2026-08-01", "value": 4.1, "change_prior": 0.0, "change_year": -0.2, "change_year_pct": null } ] } } } ``` The live event carries every series in the release: ten for the jobs report, six for job openings, eight for jobless claims. `date` is the reference period, not the release date, the same convention the Labor Market API uses. For `jobless_claims` the header `date` is the week the initial claims cover; the continued claims and insured unemployment rate entries are dated one week earlier, as the release states them. Weekly values carried by the event are the advance figures; the snapshot and history endpoints serve the final figures once published. ### `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). > [!NOTE] > > 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. ### `interest_rates.created` Fires when a central bank changes its policy rate. One event per bank per change, dated the first day the new rate is in effect. A Federal Reserve decision arrives the same afternoon it is announced. The other banks' daily series is published once a week, so their events arrive up to nine days after the decision. Shape: [print-level](#print-level), carrying `interest_rates` plus `bank`. The array holds one entry, the bank's row for that day, identical to that bank's entry in [`GET /macro/interest-rates/snapshot`](/api/macro/interest-rates/snapshot). For the Federal Reserve the rate is the midpoint of the target range. ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "id": "f2a6c1d4-8b3e-4c7f-a9d0-5e6f7a8b9c0d", "type": "interest_rates.created", "api_version": "2026-05-20", "livemode": true, "created": 1790000000, "data": { "object": { "date": "2026-09-17", "bank": "FED", "interest_rates": [ { "bank": "FED", "name": "Federal Reserve", "date": "2026-09-17", "rate": 3.875 } ] } } } ``` ### `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, within minutes of the afternoon posting. 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 | Within minutes of each afternoon's yield curve posting, each monthly inflation and labor market release, and within the hour of the weekly jobless claims release; a Federal Reserve rate decision the same afternoon, the other central banks once the weekly series carrying the change is published. | ## 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. # x402 Source: https://docs.financialdatasets.ai/x402 Access the Financial Datasets API without an API key by paying per request with x402. ## Overview [x402](https://www.x402.org) is an open payment protocol. A client pays for each HTTP request with USDC on [Base](https://base.org). No API key or account is required. Requests that include an `X-API-KEY` header are billed to that account as usual. x402 applies only to requests without a key. ## How it works 1. The client calls an endpoint with no `X-API-KEY` header. 2. The API returns `402 Payment Required`. The `PAYMENT-REQUIRED` header contains the payment terms: the amount, the USDC contract on Base, and the receiving address. 3. The client signs a USDC transfer authorization for that amount and retries the request with a `PAYMENT-SIGNATURE` header. 4. The API verifies the signature with the payment facilitator, returns the data, and settles the payment on-chain. The response includes a `PAYMENT-RESPONSE` header with the transaction hash. The x402 client libraries handle steps 2 to 4. ## Supported endpoints Every documented `GET` data endpoint accepts x402. Parameters and response formats are the same as with an API key. The amount differs by endpoint; read it from the `PAYMENT-REQUIRED` header. ### Prices and metrics | Endpoint | Data | | - | - | | [`GET /prices`](/api/prices/historical) | Historical end-of-day prices | | [`GET /prices/snapshot`](/api/prices/snapshot) | Real-time price | | [`GET /financial-metrics`](/api/financial-metrics/historical) | Historical financial metrics | | [`GET /financial-metrics/snapshot`](/api/financial-metrics/snapshot) | Real-time financial metrics | ### Financial statements | Endpoint | Data | | - | - | | [`GET /financials`](/api/financials/all-financial-statements) | All three statements in one call | | [`GET /financials/income-statements`](/api/financials/income-statements) | Income statements | | [`GET /financials/balance-sheets`](/api/financials/balance-sheets) | Balance sheets | | [`GET /financials/cash-flow-statements`](/api/financials/cash-flow-statements) | Cash flow statements | | [`GET /financials/segments`](/api/financials/all-segments) | Segment breakdowns from all three statements | | [`GET /financials/income-statements/segments`](/api/financials/income-statement-segments) | Revenue and operating income by segment | | [`GET /financials/balance-sheets/segments`](/api/financials/balance-sheet-segments) | Assets and goodwill by segment | | [`GET /financials/cash-flow-statements/segments`](/api/financials/cash-flow-statement-segments) | Capital expenditure by segment | ### Company, filings, earnings, and news | Endpoint | Data | | - | - | | [`GET /company/facts`](/api/company/facts/ticker) | Company profile | | [`GET /filings`](/api/filings/ticker) | SEC filings list with document links | | [`GET /earnings`](/api/earnings) | Earnings results and estimates, or the feed without a ticker | | [`GET /news`](/api/news/company) | Company news, or market news without a ticker | ### Ownership and holdings | Endpoint | Data | | - | - | | [`GET /insider-trades`](/api/insider-trades) | Form 4 insider transactions | | [`GET /insider-ownership`](/api/insider-ownership) | Form 3 and 5 insider holdings | | [`GET /beneficial-ownership`](/api/beneficial-ownership) | Schedule 13D and 13G holdings | | [`GET /activist-ownership`](/api/activist-ownership) | Schedule 13D activist holdings | | [`GET /institutional-holdings`](/api/institutional-holdings/ticker) | 13F holdings by filer or by ticker | | [`GET /index-funds`](/api/index-funds/ticker) | ETF and index fund constituents and weights | ### Macro | Endpoint | Data | | - | - | | [`GET /macro/interest-rates`](/api/macro/interest-rates/historical) | Central bank policy rate history | | [`GET /macro/interest-rates/snapshot`](/api/macro/interest-rates/snapshot) | Latest policy rates | | [`GET /macro/yield-curve`](/api/macro/yield-curve/historical) | US Treasury yield curve history | | [`GET /macro/yield-curve/snapshot`](/api/macro/yield-curve/snapshot) | Latest yield curve | | [`GET /macro/inflation`](/api/macro/inflation/historical) | CPI and PCE history | | [`GET /macro/inflation/snapshot`](/api/macro/inflation/snapshot) | Latest inflation prints | | [`GET /macro/labor`](/api/macro/labor/historical) | Jobs report, JOLTS, and claims history | | [`GET /macro/labor/snapshot`](/api/macro/labor/snapshot) | Latest labor prints | | [`GET /macro/gpu-prices`](/api/macro/gpu-prices/historical) | GPU rental price index history | | [`GET /macro/gpu-prices/snapshot`](/api/macro/gpu-prices/snapshot) | Latest GPU rental prices | ### IPOs and KPIs | Endpoint | Data | | - | - | | [`GET /ipos`](/api/ipos) | SEC IPO filings with cover-page details | | [`GET /kpi/metrics`](/api/kpi/metrics) | Operating KPIs from earnings releases | | [`GET /kpi/guidance`](/api/kpi/guidance) | Forward guidance from earnings releases | | [`GET /kpi/non-gaap`](/api/kpi/non-gaap) | Non-GAAP metrics with GAAP equivalents | Not covered: `GET /filings/items` (an asynchronous job tied to an account), `GET /prices/snapshot/market`, the `POST` endpoints, and the free helper lists such as `/prices/tickers` and `/macro/inflation/series`, which need no payment. Those endpoints and older data require an [API key](/quickstart). ## Requirements * A wallet on Base whose private key the client holds. The client signs each payment locally. * USDC on Base in that wallet. * No ETH is needed. The facilitator pays the gas. ## Example ```python Python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # pip install "x402[evm]" requests import os from eth_account import Account from x402 import x402ClientSync from x402.http.clients.requests import x402_requests from x402.mechanisms.evm import EthAccountSigner from x402.mechanisms.evm.exact import ExactEvmScheme account = Account.from_key(os.environ["WALLET_PRIVATE_KEY"]) client = x402ClientSync() client.register("eip155:8453", ExactEvmScheme(EthAccountSigner(account))) session = x402_requests(client) response = session.get( "https://api.financialdatasets.ai/earnings?ticker=NVDA&limit=4" ) print(response.status_code) # 200 print(response.headers["PAYMENT-RESPONSE"]) # base64 receipt with the transaction hash print(response.json()["earnings"][0]) ``` ```typescript TypeScript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} // npm install @x402/fetch @x402/evm viem import { privateKeyToAccount } from "viem/accounts"; import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; import { ExactEvmScheme } from "@x402/evm"; const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`); const client = new x402Client(); client.register("eip155:8453", new ExactEvmScheme(account)); const fetchWithPayment = wrapFetchWithPayment(fetch, client); const response = await fetchWithPayment( "https://api.financialdatasets.ai/earnings?ticker=NVDA&limit=4" ); console.log(response.status); // 200 console.log(response.headers.get("PAYMENT-RESPONSE")); // base64 receipt with the transaction hash console.log((await response.json()).earnings[0]); ``` ```bash cURL theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} # Without a client library, the request returns the 402 and the payment terms. curl -i "https://api.financialdatasets.ai/earnings?ticker=NVDA&limit=4" # HTTP/2 402 # payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50IHJlcXVpcmVkIi... # {"error": "Payment required", "message": "Send an X-API-KEY header, or pay per call with x402 ..."} ``` ## Payment terms The `PAYMENT-REQUIRED` header is base64-encoded JSON: ```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}} { "x402Version": 2, "resource": { "url": "https://api.financialdatasets.ai/earnings", "mimeType": "application/json" }, "accepts": [ { "scheme": "exact", "network": "eip155:8453", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "", "payTo": "0xC45E70793C01C6Ae4336dd5a5503baC958d32403", "maxTimeoutSeconds": 300 } ] } ``` | Field | Value | | - | - | | `network` | `eip155:8453` (Base mainnet) | | `asset` | USDC contract on Base | | `amount` | Amount in USDC base units (6 decimals) | | `payTo` | Financial Datasets receiving address | Read the amount from the header on each request. ## Receipts Every paid `200` response includes a `PAYMENT-RESPONSE` header. It is base64-encoded JSON with `success`, `network`, `payer`, and `transaction` (the on-chain transaction hash). ## Limits * **History.** x402 requests return data from the last 365 days. A request for older data only returns `403` with the window start date. Full history requires an [API key](/quickstart). * **Rate limit.** 10,000 requests per minute per wallet. * **Pagination.** `next_page_url` works the same as with an API key. Each page is a separate paid request. * **Settlement.** Payment is settled only after a successful response. Error responses are not charged. * **License.** Data accessed with x402 is for Non-Professional use. Professional use requires a plan at [financialdatasets.ai](https://financialdatasets.ai). ## Errors Payment errors return `402` with a JSON body. The `error` field identifies the cause. | `error` | Meaning | | - | - | | `Payment required` | No payment was included. Sign a payment from the `PAYMENT-REQUIRED` terms and retry. | | `duplicate_payment` | The signature was already used. Sign a new payment. | | `payer_blocked` | Recent payments from this wallet failed to settle. Check the USDC balance and retry later. | | `settlement_failed` | Verification passed but the on-chain transfer failed. No data was returned and nothing was charged. | A `503` with a `Retry-After` header means the facilitator is temporarily unavailable. Retry after the given interval. ## Related > [card] [Agent Onboarding](/agents) > > Create an API key programmatically for endpoints and history not covered by x402. > [card] [Endpoint map](https://www.financialdatasets.ai/llms.txt) > > Every endpoint with parameters, in llms.txt form. > [card] [Announcement](https://www.financialdatasets.ai/news/x402) > > Introducing x402 payments, on the Financial Datasets news page.