# FinancialMD > AI-native financial terminal for agents and the people who direct them. Financial statement data where every number carries proof back to the filing it came from. Every read is point-in-time. No account is needed. FinancialMD serves standardized and as-reported financial statements from primary sources (SEC EDGAR first). The API is JSON over HTTPS on two hosts with identical routes: - https://api.financial.md: no key needed; daily limits per IP address. API keys (Authorization: Bearer fmd_live__) are not issued publicly yet; https://financial.md/keys says when they open. - https://agent.financial.md: reserved for per-call payment (x402), which is not switched on yet. Metered routes there answer 402 and the body points back to https://api.financial.md. Use https://api.financial.md today. - OAuth 2.1 for MCP clients and connectors: authorization server metadata at https://api.financial.md/.well-known/oauth-authorization-server (dynamic registration, PKCE S256, no account). Its tokens carry the keyless limits in an allowance of their own. ## How to call it Identify a company as `company=ticker:AAPL` (optionally `ticker:AAPL.XNAS`), `company=cik:320193` or `company=fmd_`; a bare `AAPL` is a ticker and bare digits are a CIK. The response tells you what matched in `meta.company.matched_by`. Every successful response is an envelope: `{ "data": ..., "meta": { request_id, as_of, company, coverage, pipeline_version, licence, terms, proof_base } }`. Every number is a value object, never a bare number: `{ value, unit, currency, decimals, period: {start, end, type, fiscal_year, fiscal_period}, known: {from, to}, restated, method, calc_type, proof: {id, accession, form, filed, taxonomy, tag, dims, source_url, page, anchor} }`. Resolve any `proof.id` at GET /proof/{id} to see the filing and the raw as-reported facts behind the value. ## Point in time - `as_of=YYYY-MM-DD` (or a timestamp) on any read route returns what was known at that instant: facts whose `known` interval contains it. - `original=true` returns the first-reported version of each period. - `history=true` returns every knowledge version of each period, oldest first, so restatements are visible (`restated`, `restatement_kind`). - GET /v1/changes?since= lists facts whose knowledge interval opened since then. ## Routes - GET /healthz: Liveness and database reachability - GET /openapi.json: OpenAPI 3.1 document - GET /llms.txt: llms.txt discovery file - GET /skill.md: Agent skill file - GET /llms-full.txt: The whole reference in one text file: every route, parameter, ratio formula and recipe - GET /docs: Interactive API reference (Swagger UI over openapi.json) - GET /changelog: Dated changelog of the API and the MCP server (Markdown) - GET /changelog.json: The changelog as JSON - GET /robots.txt: Crawler rules: documents open, data routes closed to crawlers - GET /pricing.json: Prices per route, free limits and per-call payment status as JSON - GET /v1/companies: Company directory with filters and cursor paging - GET /v1/company/profile: Company profile, listings and available datasets - GET /v1/company/financials/{statement}/standardized: Standardized statement with point-in-time, original and history views - GET /v1/company/financials/{statement}/as_reported: The filer's own line items with tags and dimensions - GET /v1/company/ratios: Ratios computed from standardized facts, each with the proofs of its inputs - GET /v1/company/ratios/daily/{ratio_id}: One ratio as a series over periods - GET /v1/company/metrics: Concept rows of the company's reporting template - GET /v1/company/filings: Filing index for a company - GET /v1/filing/{accession}: One filing by accession number - GET /v1/filing/{accession}/document: Links to a filing's documents on EDGAR, or with format=html the primary document itself - GET /v1/filing/{accession}/facts: Every mapped fact a filing tagged, grouped by statement, in one call - GET /v1/company/ownership/insiders: Insider transactions of a company from Forms 3, 4 and 5, newest first - GET /v1/company/ownership/institutional: Institutional holders of a company from Form 13F, by quarter, with the change against the prior quarter - GET /v1/ownership/institutional/holders: Form 13F managers with their newest filing; name search and cursor paging - GET /v1/ownership/institutional/holdings: One Form 13F manager's portfolio for a quarter - GET /v1/company/stock_prices: Daily bars of a company's listing built from trades at IEX only: not the consolidated tape, not adjusted - GET /v1/company/splits: Stock splits as filed in XBRL, with whether IEX prices confirm them - GET /v1/company/dividends: Dividends per share declared or paid in each period, as filed - GET /v1/events_calendar: Earnings releases (8-K Item 2.02 filed) and model-expected dates, for one company or all - GET /v1/company/events: 8-K items a company filed: a filing-based event feed - GET /v1/news: News from 8-K filings across all companies, newest first, with event type and importance per item (not wire news) - GET /v1/search/filings: Keyword search across EDGAR documents since 2001, through SEC EDGAR full-text search - GET /v1/coverage: Every dataset FinancialMD serves, and those it does not (licensed, not built, or waiting on a decision) with alternatives - GET /v1/company/segments: As-reported segment facts (business, geography, product) from the SEC Financial Statement Data Sets - GET /v1/company/ownership/insider_holders: What each insider owned after their latest Form 4 or 5 transaction - GET /v1/company/ownership/funds: Funds holding the company in their latest Form N-PORT - GET /v1/funds: Form N-PORT funds (series) with their latest report; name search - GET /v1/fund/holdings: One fund's Form N-PORT holdings for a report period - GET /v1/company/kpis: Company-reported metrics (adjusted non-GAAP measures and operating KPIs) read from earnings releases and reports, each with its exact citation - GET /v1/company/dividend_events: Cash dividends with declaration, record, ex and pay dates as the company's filings state them, each with how it was captured and the citation - GET /v1/company/ownership/insider_holdings: Holding lines of Forms 3, 4 and 5 as filed (a Form 3 initial statement is only these) - GET /v1/fund/profile: A fund's type and ETF flag from Form N-CEN, and each share class's prospectus fees and expense ratio - GET /v1/company/identifiers: LEI and FIGI identifiers of a company with their evidence - GET /v1/screen: Screen every covered company on latest-period metrics with range filters, sorting and paging - GET /v1/company/estimates: Not covered: consensus estimates are licensed; answers 404 not_covered with alternatives - GET /v1/company/analyst_ratings: Not covered: analyst ratings and price targets are licensed; answers 404 not_covered - GET /v1/company/transcripts: Not covered: call transcripts and audio are licensed; answers 404 not_covered with alternatives - GET /v1/company/stock_prices/intraday: Not covered: real-time and intraday prices are licensed; answers 404 not_covered - GET /v1/company/logo: Not covered: logos wait on a trademark review; answers 404 not_covered - GET /v1/politician_trades: Not covered: politician trades wait on a legal review; answers 404 not_covered - GET /v1/fund_letters: Not covered: fund letters are not built; answers 404 not_covered - GET /proof/{id}: Proof for a served value and the raw facts behind it - POST /v1/verify: Check a number against the filed value - GET /v1/changes: Standardized facts whose knowledge interval opened since a time - GET /v1/request-data: How to tell us what data you needed and did not find (the body POST /v1/request-data takes) - POST /v1/request-data: Tell us what data you needed and did not find; free, keyless, never charged - GET /v1/request-data/{id}: Status of a data request (new, triaged, planned, done, wontfix), its public note and, once done, where it is served - GET /v1/requested: Requested and shipped: the reviewed demand items with their status and vote counts, aggregate only - GET /v1/me: The caller's principal, plan and limits (API key required) Standardized statements take `period_type=annual|quarterly|ltm|ytd` and `limit` (number of periods, most recent first). `data.rows[].cells` is aligned with `data.periods` (a value object or null per period; with history=true `{ versions }` oldest first). The concept ids come from GET /v1/company/metrics (with display order and formulas for subtotals). List routes return `data = { items, next_cursor }`. GET /v1/me tells a keyed caller its remaining limits. ## Verify a number POST /v1/verify with `{ "company": "ticker:AAPL", "concept": "income_statement_total_revenues", "period": "FY2024", "value": 391035000000 }`. The answer has `verdict` (matches, differs or unknown), the filed value object with proof, `delta`, the `tolerance` derived from the filer's decimals, and a `scale_hint` when your number is off by a power of ten. ## Limits - Keyless on api.financial.md: 25 metered calls a day per IP; metadata and the filing layer (standardized, as_reported, filings) 1000 a day per IP. - API keys with higher limits are not issued yet. There are no paid plans. - Every response carries RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset and RateLimit-Policy; a 429 carries Retry-After. - Per-call payment on agent.financial.md is not switched on yet. The x-price field in the OpenAPI document is the planned price per call, not a charge. ## Prices Planned prices; nothing is charged until per-call payment on agent.financial.md is switched on: every per-call x402 price is at least $0.005, and answers stay within the $1 default cap of x402 v2 clients. - fields (served): free. The filing layer and metadata (companies, profile, as_reported, filings, filing facts, ownership, funds, prices, dividends, events, identifiers, changes, proof): free, rate limited. - standardized (served): $0.005 per call over x402; $0.002 from a funded key's credits. - ratios (served): $0.005 per call over x402; $0.002 from a funded key's credits. - as_filed (planned): $0.02 per call over x402. - verify (served): $0.02 per call over x402. - value (planned): $0.02 per call over x402. - kpis (served): $0.05 per call over x402. Company-reported metrics with exact citations. - segments (served): $0.05 per call over x402. - screen (served): $0.05 per call over x402. - peers (planned): $0.05 per call over x402. - filing_diff (planned): $0.05 per call over x402. - brief (planned): $0.25 per call over x402. One free a day per caller. Above the v1 x402-fetch default cap of $0.10; within the v2 cap of $1. - research_cached (planned): $0.25 per call over x402. The latest written briefing. Above the v1 x402-fetch default cap of $0.10; within the v2 cap of $1. - research_fresh (planned): not sold per call over x402; $2.00 from a funded key's credits. A new multi-analyst run, asynchronous with a webhook, bought with credits; not sold per call over x402 until the upto scheme is widely supported, because $2 is above every default client cap. ## What is not here GET /v1/coverage lists every dataset with its status. Licensed data FinancialMD does not carry (Street consensus estimates, analyst ratings and price targets, earnings call transcripts and audio, real-time and intraday prices, CUSIP and ISIN, Morningstar research, wire news) is conceded, and datasets not built yet or waiting on a decision (fund letters, model estimates, politician trades, logos) are named too. Their paths (/v1/company/estimates, /v1/company/analyst_ratings, /v1/company/transcripts, /v1/company/stock_prices/intraday, /v1/company/logo, /v1/politician_trades, /v1/fund_letters) answer 404 `not_covered` at once with `error.details` { dataset, status, reason, licence, alternatives }: do not retry them; use an alternative. ## Errors `{ "error": { "code", "message", "docs", "request_id", "remedies": [...] } }` with codes invalid_request, unknown_company, unknown_concept, not_covered (with available_datasets), rate_limited, payment_required, unauthorized, upstream_unavailable, not_found. Errors are never charged. ## Missing something? If a dataset, field, company or analysis you need is missing, POST https://api.financial.md/v1/request-data with `{ "kind": "dataset", "want": "what you needed", "why": "the task it blocks" }` (MCP tool request_data). Free, no key, takes seconds; we review requests weekly. Unmet answers carry a remedy of kind request_data. Similar requests merge into one demand item and count as votes. The answer carries `request_id`, `item_id`, the status and the vote counts. Follow it with GET https://api.financial.md/v1/request-data/{request_id} (MCP tool request_status): new, triaged, planned, done (with the endpoint or tool that serves it) or wontfix (with a note; licensed or terms-restricted data is not redistributed). What was requested and what shipped: https://financial.md/requested, as JSON at https://api.financial.md/v1/requested. ## Files - OpenAPI 3.1: https://api.financial.md/openapi.json - Skill: https://api.financial.md/skill.md - Everything in one file: https://api.financial.md/llms-full.txt - Interactive reference: https://api.financial.md/docs - Changelog: https://api.financial.md/changelog - Prices as JSON: https://api.financial.md/pricing.json - Guide for AI agents: https://financial.md/docs/agents - Docs: https://financial.md/docs - Terms: https://financial.md/terms (information only, not investment advice) - Privacy: https://financial.md/privacy - Proof pages: https://financial.md/proof/{id} ## Route reference ### GET /v1/companies Company directory with filters and cursor paging. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Search or page the company directory. Use it to turn a name into a company id, or to list every company with a dataset. Each item has `fmd_id`, `cik`, `primary_ticker` and `available_datasets`. Example: `GET https://api.financial.md/v1/companies?q=Apple&limit=5` Parameters: - `q` (query): Name or ticker search (names as substring, tickers as prefix; case-insensitive) - `country` (query): ISO 3166-1 alpha-2 - `exchange` (query): MIC of a listing, e.g. XNAS - `template` (query): Reporting template - `status` (query): Company status - `updated_since` (query): Companies updated since this date or timestamp - `limit` (query): Maximum companies per page - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Companies page ### GET /v1/company/profile Company profile, listings and available datasets. Route class metadata; planned price 0 USD per call on the agent host (not charged today). One company's identity: CIK, listings with exchange codes, sector, industry, reporting template, fiscal year end and which datasets are served. Call it first when you are unsure a ticker is covered. Example: `GET https://api.financial.md/v1/company/profile?company=ticker:AAPL` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik Answer: Profile ### GET /v1/company/financials/{statement}/standardized Standardized statement with point-in-time, original and history views. Route class filing_layer; planned price 0.005 USD per call on the agent host (not charged today). A financial statement on the FinancialMD template, so line items compare across companies. Use it for questions such as "What was Apple's revenue in fiscal 2024?" or "What is AAPL's free cash flow?". `data.periods` is most recent first and `row.cells[i]` is the value object for `periods[i]`, each with the 10-K or 10-Q it came from. Add `as_of` for what was known on a date, `original=true` for first-reported values, `history=true` for every restatement. Example: `GET https://api.financial.md/v1/company/financials/income_statement/standardized?company=ticker:AAPL&period_type=annual&limit=5` Parameters: - `statement` (path, required): Statement; `supplemental` carries share counts and per-share figures - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period_type` (query): Period type - `limit` (query): Maximum periods (most recent first) - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `original` (query): First-reported version of each period - `history` (query): Every knowledge version of each period, oldest first Answer: Standardized statement ### GET /v1/company/financials/{statement}/as_reported The filer's own line items with tags and dimensions. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). The same grid with the filer's own line items: one row per XBRL tag and dimension as filed. Use it when you need the company's exact label or a line the template folds into a total. Example: `GET https://api.financial.md/v1/company/financials/balance_sheet/as_reported?company=cik:320193&period_type=annual&limit=2` Parameters: - `statement` (path, required): Statement - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period_type` (query): Period type (as-reported serves annual and quarterly; balance sheets are instants at the period end) - `limit` (query): Maximum periods - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `history` (query): Every filing's version of each line and period, oldest first - `accession` (query): Only facts from this filing Answer: As-reported facts ### GET /v1/company/ratios Ratios computed from standardized facts, each with the proofs of its inputs. Route class metered; planned price 0.005 USD per call on the agent host (not charged today). Margins, returns, leverage, liquidity, growth and per-share ratios for each period, computed from the standardized facts. Each ratio carries the proof ids of its inputs, so it can be traced to the filing. Example: `GET https://api.financial.md/v1/company/ratios?company=ticker:AAPL&period_type=annual&limit=5` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period_type` (query): Period type - `limit` (query): Maximum periods (most recent first) - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. Answer: Ratios computed from the standardized facts known at as_of, then valuation ratios (market cap, EV, P/E, P/S, P/B, EV/EBITDA, EV/EBIT, FCF and dividend yield) at the last IEX close on or before each period end; every cell's proof lists its inputs, the close first for valuation (docs/ratios.md). ### GET /v1/company/ratios/daily/{ratio_id} One ratio as a series over periods. Route class metered; planned price 0.005 USD per call on the agent host (not charged today). One ratio as a series. Fundamental ratios have one point per fiscal period; valuation ratios (market cap, P/E, EV/EBITDA and others) have one point per trading session, pairing the IEX close with the facts known that evening. Example: `GET https://api.financial.md/v1/company/ratios/daily/gross_margin?company=ticker:AAPL&period_type=annual&limit=10` Parameters: - `ratio_id` (path, required): Ratio id from GET /v1/company/metrics?statement=ratios - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period_type` (query): Period type - `limit` (query): Maximum periods (most recent first); sessions for a valuation ratio - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `ticker` (query): Valuation ratios: the listing whose close is used - `from` (query): Valuation ratios: first session, inclusive - `to` (query): Valuation ratios: last session, inclusive - `cursor` (query): Opaque cursor from meta.next_cursor Answer: A fundamentals ratio: one point per fiscal period. A valuation ratio: one point per trading session with an IEX bar (period_type daily), each using the facts known that evening; it takes ticker, from, to, limit (default 250, at most 1,000) and cursor. ### GET /v1/company/metrics Concept rows of the company's reporting template. Route class metadata; planned price 0 USD per call on the agent host (not charged today). The concept ids, labels, display order and subtotal formulas of the company's template. Use the ids in `/v1/screen`, `/v1/verify` and to read statement rows. `statement=ratios` lists the ratio ids and formulas. Example: `GET https://api.financial.md/v1/company/metrics?company=ticker:AAPL&statement=income_statement` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `statement` (query): Only this statement; `ratios` lists the serve-time ratios with their formulas Answer: Template concepts ### GET /v1/company/filings Filing index for a company. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). A company's SEC filings, newest first, with accession number, form, period and filing date and an EDGAR link. Example: `GET https://api.financial.md/v1/company/filings?company=ticker:AAPL&form=10-K&limit=5` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `form` (query): Form type, e.g. 10-K - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum filings - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Filings page, newest first ### GET /v1/filing/{accession} One filing by accession number. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). One filing by accession number: form, fiscal period, filing and acceptance times, primary document and EDGAR link. Example: `GET https://api.financial.md/v1/filing/0000320193-24-000123` Parameters: - `accession` (path, required): Accession number, e.g. 0000320193-24-000123 Answer: Filing ### GET /v1/filing/{accession}/document Links to a filing's documents on EDGAR, or with format=html the primary document itself. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Links to every document of a filing on EDGAR. `format=html` returns the primary document itself. Example: `GET https://api.financial.md/v1/filing/0000320193-24-000123/document` Parameters: - `accession` (path, required): Accession number - `format` (query): json: the links; html: the primary document as EDGAR serves it (relative links resolve to EDGAR) Answer: The filing's document links, or the primary document ### GET /v1/filing/{accession}/facts Every mapped fact a filing tagged, grouped by statement, in one call. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Every fact one filing tagged that maps to a statement concept, grouped by statement, in one call. Use it to read what a single 10-K or 10-Q said. Example: `GET https://api.financial.md/v1/filing/0000320193-24-000123/facts?statement=income_statement` Parameters: - `accession` (path, required): Accession number - `statement` (query): Only this statement - `limit` (query): Maximum facts Answer: The filing and the facts it tagged that map to a standardized concept, grouped by statement in display order. Tags without a mapping are not included. ### GET /v1/company/ownership/insiders Insider transactions of a company from Forms 3, 4 and 5, newest first. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Insider transactions from Forms 3, 4 and 5, newest first: who, role, transaction code, shares, price and the filing. Example: `GET https://api.financial.md/v1/company/ownership/insiders?company=ticker:AAPL&limit=20` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum transactions - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Transaction lines, newest transaction first. Holdings-only lines (Form 3) are not served. ### GET /v1/company/ownership/institutional Institutional holders of a company from Form 13F, by quarter, with the change against the prior quarter. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Form 13F managers that reported a position in the company for a quarter, with shares, value and the change against the prior quarter. Example: `GET https://api.financial.md/v1/company/ownership/institutional?company=ticker:AAPL&limit=20` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period` (query): Calendar quarter end the holdings are reported for - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum positions - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Positions in the company's securities for one quarter end, largest value first. Without `period` the newest quarter whose 45-day filing window has closed is served. ### GET /v1/ownership/institutional/holders Form 13F managers with their newest filing; name search and cursor paging. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Search Form 13F managers by name. Each has a CIK to pass to `/v1/ownership/institutional/holdings`. Example: `GET https://api.financial.md/v1/ownership/institutional/holders?q=Berkshire` Parameters: - `q` (query): Manager name search (case-insensitive substring) - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum managers - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Managers by name, each with its newest filing ### GET /v1/ownership/institutional/holdings One Form 13F manager's portfolio for a quarter. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). One Form 13F manager's portfolio for a quarter, largest positions first. Example: `GET https://api.financial.md/v1/ownership/institutional/holdings?holder=cik:1067983&period=2026-06-30&limit=20` Parameters: - `holder` (query, required): The manager's SEC CIK - `period` (query): Calendar quarter end the holdings are reported for - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum positions - `cursor` (query): Opaque cursor from meta.next_cursor Answer: The manager's positions for one quarter end (default: its newest), largest value first ### GET /v1/company/stock_prices Daily bars of a company's listing built from trades at IEX only: not the consolidated tape, not adjusted. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Daily bars built from trades at IEX only. This is not the consolidated tape and the close is not the official close. `adjust=splits` adds split-adjusted values; `adjust=total_return` adds dividend-reinvested values. Example: `GET https://api.financial.md/v1/company/stock_prices?company=ticker:AAPL&from=2026-10-01&to=2026-10-31` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `ticker` (query): One of the company's listings; default is the ticker named in `company`, else the primary listing with bars - `from` (query): First session, inclusive - `to` (query): Last session, inclusive - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum sessions - `cursor` (query): Opaque cursor from meta.next_cursor - `adjust` (query): splits: each bar also carries split_adjusted values (confirmed splits after the session only); total_return: also total_return values (split-adjusted times the dividend factors of every ex-date after the session) Answer: Daily bars, newest session first. Built from trades executed at IEX only: a small share of consolidated volume, not the official closing price, not adjusted for splits or dividends. `meta.attribution` carries the citation IEX requires. ### GET /v1/company/splits Stock splits as filed in XBRL, with whether IEX prices confirm them. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Stock splits as filed in XBRL, each with whether IEX prices confirm it. Example: `GET https://api.financial.md/v1/company/splits?company=ticker:AAPL` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. Answer: Stock splits as filed in XBRL, with whether IEX prices confirm them. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/company/dividends Dividends per share declared or paid in each period, as filed. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Dividends per share declared or paid in each fiscal period, as filed, with proof. Example: `GET https://api.financial.md/v1/company/dividends?company=ticker:AAPL&limit=8` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `kind` (query): Only declared or only paid - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum periods Answer: Dividends per share declared or paid in each period, as filed. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/events_calendar Earnings releases (8-K Item 2.02 filed) and model-expected dates, for one company or all. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Earnings releases (8-K Item 2.02 filed) and model-expected report dates, for one company or for every company in a date range. Example: `GET https://api.financial.md/v1/events_calendar?company=ticker:AAPL` Parameters: - `company` (query): Optional: one company - `from` (query): First date, inclusive - `to` (query): Last date, inclusive - `confidence` (query): confirmed: 8-K Item 2.02 filed; predicted: cadence model - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum events - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Earnings releases (8-K Item 2.02 filed) and model-expected dates, for one company or all. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/company/events 8-K items a company filed: a filing-based event feed. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). A company's 8-K filings with the items they report (earnings, leadership changes, agreements and others), newest first. Example: `GET https://api.financial.md/v1/company/events?company=ticker:AAPL&limit=10` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `event_type` (query): Only items of this type - `importance_min` (query): Only filings whose highest item is at least this important - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum items - `cursor` (query): Opaque cursor from meta.next_cursor Answer: 8-K items a company filed: a filing-based event feed. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/news News from 8-K filings across all companies, newest first, with event type and importance per item (not wire news). Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). 8-K filings across every company, newest first, each with its items, event types, a headline and an importance from 1 to 5 (FinancialMD's rule by item number). importance_min=4 gives the top stories: earnings, M&A, impairments, auditor changes, restatements, bankruptcies. Built from EDGAR, not wire news. Example: `GET https://api.financial.md/v1/news?importance_min=4&limit=20` Parameters: - `company` (query): Optional: one company - `event_type` (query): Only filings with an item of this type - `importance_min` (query): Only filings whose highest item is at least this important (FinancialMD's rule by 8-K item; see note) - `from` (query): Accepted on or after this date (UTC) - `to` (query): Accepted on or before this date (UTC) - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum filings - `cursor` (query): Opaque cursor from meta.next_cursor Answer: 8-K filings across all companies, newest first, one item per filing with its items, event types and importance. Built from EDGAR's own item list; not wire news. ### GET /v1/search/filings Keyword search across EDGAR documents since 2001, through SEC EDGAR full-text search. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Find the EDGAR documents (filings and exhibits since 2001) that contain words or a quoted phrase, through SEC EDGAR full-text search. Each hit names its filing, form, date and companies with FinancialMD ids, and links the document. Example: `GET https://api.financial.md/v1/search/filings?q=%22going%20concern%22&forms=10-K&limit=10` Parameters: - `q` (query, required): Words to find; a phrase in double quotes matches exactly - `forms` (query): Comma-separated form types - `company` (query): Optional: only this company's documents - `from` (query): Filed on or after - `to` (query): Filed on or before - `page` (query): Page number, 1-based - `limit` (query): Maximum documents per page Answer: Documents that contain the words, best match first, from SEC EDGAR full-text search (filings since 2001). Each names its filing and the companies on it, with FinancialMD ids where known. ### GET /v1/coverage Every dataset FinancialMD serves, and those it does not (licensed, not built, or waiting on a decision) with alternatives. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Which datasets FinancialMD serves and which it does not (licensed, not built, or waiting on a decision), with the routes, MCP tools, reason and alternatives for each. Read it before looking for consensus estimates, transcripts or real-time prices. Example: `GET https://api.financial.md/v1/coverage?status=conceded` Parameters: - `status` (query): Only datasets with this status Answer: Every dataset with its status, routes, MCP tools, the reason when it is not served, and alternatives ### GET /v1/company/segments As-reported segment facts (business, geography, product) from the SEC Financial Statement Data Sets. Route class filing_layer; planned price 0.05 USD per call on the agent host (not charged today). As-reported segment facts: revenue and other lines by business segment, geography or product. Example: `GET https://api.financial.md/v1/company/segments?company=ticker:AAPL&kind=geography` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period_type` (query): Annual (four quarters) or quarterly facts - `kind` (query): Segment axis kind - `tag` (query): Only this XBRL tag - `limit` (query): Maximum period ends - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. Answer: As-reported segment facts with the filer's exact periods. Every value has its proof (docs/data-contracts.md). ### GET /v1/company/ownership/insider_holders What each insider owned after their latest Form 4 or 5 transaction. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). What each insider owned after their latest Form 4 or 5 transaction. Example: `GET https://api.financial.md/v1/company/ownership/insider_holders?company=ticker:AAPL` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum holders Answer: What each insider owned after their latest Form 4 or 5 transaction. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/company/ownership/funds Funds holding the company in their latest Form N-PORT. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Funds holding the company in their latest Form N-PORT, with shares and value. Example: `GET https://api.financial.md/v1/company/ownership/funds?company=ticker:AAPL&limit=20` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `period` (query): Report period window ending on or before this date (default: the newest) - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum funds - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Funds holding the company in their latest Form N-PORT. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/funds Form N-PORT funds (series) with their latest report; name search. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Search Form N-PORT funds by name or series id. Each has a series id to pass to `/v1/fund/holdings` and `/v1/fund/profile`. Example: `GET https://api.financial.md/v1/funds?q=Vanguard%20500` Parameters: - `q` (query): Fund or registrant name, or a series id - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum funds - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Form N-PORT funds (series) with their latest report; name search. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/fund/holdings One fund's Form N-PORT holdings for a report period. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). One fund's Form N-PORT holdings for a report period, largest first. Example: `GET https://api.financial.md/v1/fund/holdings?fund=S000002839&limit=20` Parameters: - `fund` (query, required): SEC series id - `period` (query): Report period (month end); default the newest - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum holdings - `cursor` (query): Opaque cursor from meta.next_cursor Answer: One fund's Form N-PORT holdings for a report period. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/company/kpis Company-reported metrics (adjusted non-GAAP measures and operating KPIs) read from earnings releases and reports, each with its exact citation. Route class filing_layer; planned price 0.05 USD per call on the agent host (not charged today). Company-reported metrics read from earnings releases and reports: adjusted (non-GAAP) measures and operating statistics such as product-line sales. Each value carries its exact citation and a confidence. Example: `GET https://api.financial.md/v1/company/kpis?company=ticker:AAPL&kind=operating&limit=20` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `metric` (query): Only this metric slug (data.metrics lists the company's) - `kind` (query): adjusted: non-GAAP measures under the company's own definition; operating: operating statistics - `period_type` (query): Only this period type - `from` (query): First period end, inclusive - `to` (query): Last period end, inclusive - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum values - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Published company-reported values known at as_of, newest period first. Withheld values (value_conflict, unit_conflict) are never served; data.withheld counts them. ### GET /v1/company/dividend_events Cash dividends with declaration, record, ex and pay dates as the company's filings state them, each with how it was captured and the citation. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Cash dividends with declaration, record, ex and pay dates as the company's filings state them. A missing ex-date is never inferred. Example: `GET https://api.financial.md/v1/company/dividend_events?company=ticker:AAPL&limit=8` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `from` (query): First date, inclusive - `to` (query): Last date, inclusive - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum dividends Answer: Cash dividends with declaration, record, ex and pay dates as filed, the method that captured each and the citation ### GET /v1/company/ownership/insider_holdings Holding lines of Forms 3, 4 and 5 as filed (a Form 3 initial statement is only these). Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). Holding lines of Forms 3, 4 and 5 as filed. Example: `GET https://api.financial.md/v1/company/ownership/insider_holdings?company=ticker:AAPL&limit=20` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `form` (query): Only lines of this form - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum lines Answer: Holding lines of Forms 3, 4 and 5 as filed (a Form 3 is only these) ### GET /v1/fund/profile A fund's type and ETF flag from Form N-CEN, and each share class's prospectus fees and expense ratio. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). A fund's type (ETF, index fund and others) from Form N-CEN and each share class's prospectus fees and expense ratio. Accepts a series id or a share-class ticker. Example: `GET https://api.financial.md/v1/fund/profile?fund=VOO` Parameters: - `fund` (query, required): Series id or share-class ticker - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. Answer: A fund's kind and latest N-CEN census answers, and every share class with its prospectus fee table ### GET /v1/company/identifiers LEI and FIGI identifiers of a company with their evidence. Route class filing_layer; planned price 0 USD per call on the agent host (not charged today). CIK, LEI and FIGI of a company with the evidence for each. Example: `GET https://api.financial.md/v1/company/identifiers?company=ticker:AAPL` Parameters: - `company` (query, required): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. Answer: LEI and FIGI identifiers of a company with their evidence. Every number is a value object with its proof (docs/data-contracts.md). ### GET /v1/screen Screen every covered company on latest-period metrics with range filters, sorting and paging. Route class metered; planned price 0.05 USD per call on the agent host (not charged today). Screen every covered company on its latest period. `filter` takes `metric:min:max` ranges with raw values (0.2 is 20 percent), `sort` takes `metric:desc`. Each result carries one value object with proof per metric. Example: `GET https://api.financial.md/v1/screen?filter=net_margin:0.2:,income_statement_total_revenues:10000000000:&sort=net_margin:desc&limit=20` Parameters: - `status` (query): Listing status of the companies screened: active (default), delisted, inactive or all - `metrics` (query): Comma-separated columns: concept ids (GET /v1/company/metrics) or ratio ids. Up to 12. Defaults to revenue, net income, the three margins, revenue growth and return on equity. - `filter` (query): Comma-separated range filters `metric:min:max`; either bound may be empty. Values are raw: 0.1 is 10 percent, amounts are in the reporting currency. A company without a value for a filtered metric does not match. - `sort` (query): `[:asc|:desc]`; companies without a value sort last. Default name:asc. - `period_type` (query): The period type whose latest period is screened - `q` (query): Name or ticker search (names as substring, tickers as prefix) - `sector` (query): Exact sector (case-insensitive) - `industry` (query): Exact industry (case-insensitive) - `template` (query): Reporting template - `country` (query): ISO 3166-1 alpha-2 - `as_of` (query): Point in time: a date (YYYY-MM-DD, end of day UTC) or ISO timestamp. Answers what was known then. - `limit` (query): Maximum companies per page - `cursor` (query): Opaque cursor from meta.next_cursor Answer: A page of companies, each with its latest period and one value object (with proof) per metric ### GET /v1/company/estimates Not covered: consensus estimates are licensed; answers 404 not_covered with alternatives. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: consensus estimates are licensed data FinancialMD does not carry. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/estimates?company=ticker:AAPL` Answer: always 404 `not_covered`. Always 404 not_covered: consensus estimates are licensed data FinancialMD does not carry. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/estimates?company=ticker:AAPL` ### GET /v1/company/analyst_ratings Not covered: analyst ratings and price targets are licensed; answers 404 not_covered. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: analyst ratings and price targets are licensed. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/analyst_ratings?company=ticker:AAPL` Answer: always 404 `not_covered`. Always 404 not_covered: analyst ratings and price targets are licensed. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/analyst_ratings?company=ticker:AAPL` ### GET /v1/company/transcripts Not covered: call transcripts and audio are licensed; answers 404 not_covered with alternatives. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: call transcripts and audio are licensed. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/transcripts?company=ticker:AAPL` Answer: always 404 `not_covered`. Always 404 not_covered: call transcripts and audio are licensed. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/transcripts?company=ticker:AAPL` ### GET /v1/company/stock_prices/intraday Not covered: real-time and intraday prices are licensed; answers 404 not_covered. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: real-time and intraday prices are licensed; daily IEX bars are at /v1/company/stock_prices. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/stock_prices/intraday?company=ticker:AAPL` Answer: always 404 `not_covered`. Always 404 not_covered: real-time and intraday prices are licensed; daily IEX bars are at /v1/company/stock_prices. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/stock_prices/intraday?company=ticker:AAPL` ### GET /v1/company/logo Not covered: logos wait on a trademark review; answers 404 not_covered. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: logos wait on a trademark review. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/logo?company=ticker:AAPL` Answer: always 404 `not_covered`. Always 404 not_covered: logos wait on a trademark review. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/company/logo?company=ticker:AAPL` ### GET /v1/politician_trades Not covered: politician trades wait on a legal review; answers 404 not_covered. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: politician trades wait on a legal review. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/politician_trades` Answer: always 404 `not_covered`. Always 404 not_covered: politician trades wait on a legal review. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/politician_trades` ### GET /v1/fund_letters Not covered: fund letters are not built; answers 404 not_covered. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Always 404 not_covered: fund letters are not built. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/fund_letters` Answer: always 404 `not_covered`. Always 404 not_covered: fund letters are not built. error.details names the reason and what to use instead; do not retry. Example: `GET https://api.financial.md/v1/fund_letters` ### GET /proof/{id} Proof for a served value and the raw facts behind it. Route class metadata; planned price 0 USD per call on the agent host (not charged today). The proof behind any value: the filing, the XBRL tag and dimensions, the source URL and the raw as-reported facts it derives from. Example: `GET https://api.financial.md/proof/p_edt68ehn6cw3ed0` Parameters: - `id` (path, required): Proof id from any value object Answer: Proof and the raw facts behind it ### POST /v1/verify Check a number against the filed value. Route class metered; planned price 0.02 USD per call on the agent host (not charged today). Check a number you got elsewhere against what the company filed. Returns `verdict` (matches, differs or unknown), the filed value with proof, the difference, the tolerance from the filer's precision, and a `scale_hint` when your number is off by a power of ten. Example: `POST https://api.financial.md/v1/verify` with body `{"company":"ticker:AAPL","concept":"income_statement_total_revenues","period":"FY2024","value":391035000000}` Body: JSON, see the OpenAPI document. Answer: Verdict ### GET /v1/changes Standardized facts whose knowledge interval opened since a time. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Standardized facts whose knowledge interval opened since a time: new filings and restatements. Poll it to keep a local copy current. Example: `GET https://api.financial.md/v1/changes?since=2026-11-01T00:00:00Z&company=ticker:AAPL&limit=50` Parameters: - `since` (query, required): Facts whose knowledge interval opened at or after this instant - `company` (query): Company as fmd_, cik:, ticker:[.]; a bare symbol means ticker, bare digits mean cik - `limit` (query): Maximum changes - `cursor` (query): Opaque cursor from meta.next_cursor Answer: Changes page, oldest first ### GET /v1/request-data How to tell us what data you needed and did not find (the body POST /v1/request-data takes). Route class discovery; planned price 0 USD per call on the agent host (not charged today). How to tell us about data or analysis you needed and did not find: the body POST /v1/request-data takes, the kinds, the limits and how to follow a request. Example: `GET https://api.financial.md/v1/request-data` Answer: How to send a data request ### POST /v1/request-data Tell us what data you needed and did not find; free, keyless, never charged. Route class metadata; planned price 0 USD per call on the agent host (not charged today). Tell us what you needed and did not find. Free, keyless, never charged. Similar requests merge into one demand item and count as votes; the answer has request_id, item_id, status and the vote counts. Do not include personal data. Example: `POST https://api.financial.md/v1/request-data` with body `{"kind":"dataset","want":"Quarterly order backlog by segment","why":"Modeling revenue visibility","company":"ticker:BA","endpoint_or_tool":"/v1/company/kpis"}` Body: JSON, see the OpenAPI document. ### GET /v1/request-data/{id} Status of a data request (new, triaged, planned, done, wontfix), its public note and, once done, where it is served. Route class discovery; planned price 0 USD per call on the agent host (not charged today). Follow a request by the request_id POST /v1/request-data returned: new, triaged, planned, done (with served_by, the endpoint or tool) or wontfix (with a public note), and the vote counts. Example: `GET https://api.financial.md/v1/request-data/0b8f6a52-6f0e-4a8e-9a43-3c0f6b2d1e11` Parameters: - `id` (path, required): The request_id POST /v1/request-data returned, or a demand item id Answer: Status of the demand item the request belongs to ### GET /v1/requested Requested and shipped: the reviewed demand items with their status and vote counts, aggregate only. Route class discovery; planned price 0 USD per call on the agent host (not charged today). Requested and shipped: the reviewed demand items with status, public note, served_by and vote counts, and counts per status. Aggregate only, no submitter details. Example: `GET https://api.financial.md/v1/requested` Answer: Requested and shipped, aggregate only ### GET /v1/me The caller's principal, plan and limits (API key required). Route class metadata; planned price 0 USD per call on the agent host (not charged today). For a keyed caller: principal, plan and remaining limits. Needs an API key; keys are not issued publicly yet. Example: `GET https://api.financial.md/v1/me` Answer: Principal, plan and the keyed limits (10000 metadata, 250 metered a day) ## Ratio formulas Fundamentals ratios are computed from standardized facts; valuation ratios multiply an IEX close (single venue, unadjusted) by them. Formulas: - `gross_margin` (Gross margin, percent): income_statement_gross_profit / income_statement_total_revenues - `operating_margin` (Operating margin, percent): income_statement_operating_income / income_statement_total_revenues - `net_margin` (Net margin, percent): income_statement_net_income / income_statement_total_revenues - `fcf_margin` (Free cash flow margin, percent): (cash_flow_operating - cash_flow_capital_expenditures) / income_statement_total_revenues - `revenue_growth_yoy` (Revenue growth (year over year), percent): income_statement_total_revenues / income_statement_total_revenues[prior year] - 1 - `roe` (Return on equity, percent): income_statement_net_income / balance_sheet_total_equity - `roa` (Return on assets, percent): income_statement_net_income / balance_sheet_total_assets - `asset_turnover` (Asset turnover, ratio): income_statement_total_revenues / balance_sheet_total_assets - `current_ratio` (Current ratio, ratio): balance_sheet_total_current_assets / balance_sheet_total_current_liabilities - `debt_to_equity` (Debt to equity, ratio): balance_sheet_total_debt / balance_sheet_total_equity - `interest_coverage` (Interest coverage, ratio): income_statement_operating_income / income_statement_interest_expense - `eps_basic` (Earnings per share (basic), per_share): supplemental_eps_basic - `eps_diluted` (Earnings per share (diluted), per_share): supplemental_eps_diluted - `nii_to_avg_loans_securities` (Net interest income to average loans and securities, percent): income_statement_net_interest_income / (((balance_sheet_loans_net + balance_sheet_investment_securities) + (balance_sheet_loans_net[opening] + balance_sheet_investment_securities[opening])) / 2) - `efficiency_ratio` (Efficiency ratio, percent): income_statement_noninterest_expense / (income_statement_net_interest_income + income_statement_noninterest_income) - `loans_to_deposits` (Loans to deposits, ratio): balance_sheet_loans_net / balance_sheet_total_deposits - `loss_ratio` (Loss ratio, percent): income_statement_losses_and_loss_adjustment_expenses / income_statement_premiums_earned - `acquisition_cost_ratio` (Acquisition cost ratio, percent): income_statement_policy_acquisition_costs / income_statement_premiums_earned - `market_cap` (Market capitalisation, currency): close * supplemental_shares_outstanding - `enterprise_value` (Enterprise value, currency): close * supplemental_shares_outstanding + balance_sheet_total_debt - balance_sheet_cash_and_equivalents - `pe_ttm` (Price to earnings (trailing twelve months), ratio): (close * supplemental_shares_outstanding) / income_statement_net_income[ttm] - `ps_ttm` (Price to sales (trailing twelve months), ratio): (close * supplemental_shares_outstanding) / income_statement_total_revenues[ttm] - `pb` (Price to book, ratio): (close * supplemental_shares_outstanding) / balance_sheet_total_equity - `ev_ebitda_ttm` (EV to EBITDA (trailing twelve months), ratio): (close * supplemental_shares_outstanding + balance_sheet_total_debt - balance_sheet_cash_and_equivalents) / (income_statement_operating_income[ttm] + cash_flow_depreciation_and_amortization[ttm]) - `ev_ebit_ttm` (EV to EBIT (trailing twelve months), ratio): (close * supplemental_shares_outstanding + balance_sheet_total_debt - balance_sheet_cash_and_equivalents) / income_statement_operating_income[ttm] - `fcf_yield` (Free cash flow yield, percent): (cash_flow_operating[ttm] - cash_flow_capital_expenditures[ttm]) / (close * supplemental_shares_outstanding) - `dividend_yield` (Dividend yield, percent): cash_flow_dividends_paid[ttm] / (close * supplemental_shares_outstanding) ## Recipes # FinancialMD skill ## When to use - You need revenue, net income, assets, cash flow or any statement line for a public company, with a source you can cite. - You have a number from somewhere else and want to know whether it matches the filing. - You need what was known on a date (no look-ahead), or want to see restatements. ## Hosts - https://api.financial.md: no key needed; daily limits per IP address. API keys are not issued publicly yet. - https://agent.financial.md: reserved for per-call payment (x402), which is not switched on yet. Metered routes there answer 402 and the body points back to https://api.financial.md. Use https://api.financial.md today. ## Recipe 1: standardized statement 1. GET https://api.financial.md/v1/company/financials/income_statement/standardized?company=ticker:AAPL&period_type=annual&limit=5 2. Read `data.periods` (most recent first) and `data.rows[]` (one per concept, in display order); `row.cells[i]` is the value object for `periods[i]`, or null. 3. Cite `value.proof.accession`, `value.proof.form`, `value.proof.filed` and the link https://financial.md/proof/{proof.id}. Statements: income_statement, balance_sheet, cash_flow. Period types: annual, quarterly, ltm, ytd. ## Recipe 2: verify a number POST https://api.financial.md/v1/verify with JSON `{"company":"ticker:AAPL","concept":"income_statement_total_revenues","period":"FY2024","value":391035000000,"source":"analyst note"}`. - `verdict` is matches, differs or unknown. `delta` is `{ absolute, percent }`; `tolerance` is half a unit at the filer's precision (decimals -6 means millions). - `scale_hint` of 6 means your number was in millions. - Concept ids come from GET /v1/company/metrics?company=...; `metric_alias` ids are accepted too. ## Recipe 3: point in time - Add `as_of=2024-06-30` to any read route: the answer is what was known then. - `original=true`: first-reported values. `history=true`: every version per period, oldest first; look at `restated` and `restatement_kind`. - GET /v1/changes?since=2026-11-01T00:00:00Z: what was learned since (pull twin of the webhook). ## Recipe 4: the filer's own line items GET https://api.financial.md/v1/company/financials/income_statement/as_reported?company=cik:320193&period_type=annual&limit=2 returns the same grid with one row per filed line (`taxonomy`, `tag`, `dims`); annual and quarterly only. ## Recipe 5: screen every company GET https://api.financial.md/v1/screen?filter=net_margin:0.2:,revenue_growth_yoy:0.1:&sort=roe:desc&limit=20 returns the companies whose latest annual period passes every range filter, sorted on the server, each with one value object (with proof) per metric. Bounds are raw values (0.2 is 20 percent). `total` is the whole match; `next_cursor` pages it. ## Recipe 6: one filing, every statement GET https://api.financial.md/v1/filing/0000320193-24-000123/facts returns every mapped fact the filing tagged, grouped by statement. Share counts and per-share figures: GET https://api.financial.md/v1/company/financials/supplemental/standardized?company=ticker:AAPL. ## Rules - Never present a value without its proof; the envelope gives you everything for a citation. - Numbers are value objects; read `.value` and keep `.unit`, `.currency` and `.decimals`. - Respect RateLimit-* headers; on 429 wait Retry-After seconds. On 402 read remedies. - Company resolution: `ticker:SYM`, `ticker:SYM.MIC`, `cik:N`, `fmd_`; check `meta.company.matched_by`. - Missing a dataset, field, company or analysis? POST https://api.financial.md/v1/request-data with `{"kind":"dataset","want":"..."}`: free, no key, reviewed weekly. - Follow a request with GET https://api.financial.md/v1/request-data/{request_id} (new, triaged, planned, done with `served_by`, or wontfix with a note). Shipped requests: https://api.financial.md/v1/requested. - This is information, not investment advice (https://financial.md/terms). ## Budget Each recipe is one call. Keyless: 25 metered calls a day per IP (verify), 1000 filing-layer calls a day (statements, filings). The OpenAPI document at https://api.financial.md/openapi.json has every parameter. ## Changelog Changes a caller of the API or the MCP server can see, newest first. What was requested and what shipped: https://financial.md/requested (JSON: https://api.financial.md/v1/requested). To ask for something: https://financial.md/docs/request-data. ## 2026-11-13 ### Requests are merged, voted on and tracked until they ship (api) - Similar requests merge into one demand item (by kind, company and concept); a repeat request is a vote. POST /v1/request-data answers with request_id, item_id, the item's status and its request and requester counts. - GET /v1/request-data/{id} answers the status (new, triaged, planned, done or wontfix), our public note and, once done, the endpoint or tool that serves it. MCP tool request_status does the same (thirty-seven tools in all). - Requested and shipped: https://financial.md/requested lists the items a person reviewed and titled, aggregate only, with the JSON feed GET /v1/requested. Nothing is listed automatically. - People can request data or analysis from the terminal's form, the command palette, every empty or not-covered state and the footer. No email address is collected: follow a request by its id. - Data that needs a licence is closed as wontfix with a note pointing to GET /v1/coverage; later requests for it still count as votes. ### metric_alias replaces fiscal_alias (api) - Concept rows (GET /v1/company/metrics, statements, ratios) carry metric_alias: another id accepted wherever concept_id is. fiscal_alias is deprecated: it is still sent with the same value until the next release, then removed. The MCP output schemas follow. ### 8-K news, full-text search, and a coverage map with clear not_covered answers (api) - GET /v1/news: 8-K filings across all companies, newest first, each with its items, event types, a headline and an importance from 1 to 5 (FinancialMD's rule by item number). Filter by event_type, importance_min, company and dates. Not wire news. - GET /v1/company/events gains importance_min, and importance and headline on every filing. - GET /v1/search/filings: keyword search across EDGAR documents since 2001 through SEC EDGAR full-text search, with FinancialMD ids for the companies on each document. - GET /v1/coverage lists every dataset with its status. Licensed datasets (consensus estimates, analyst ratings, transcripts, real-time prices) and those not built or waiting on a decision answer 404 not_covered at their own path (/v1/company/estimates, /v1/company/analyst_ratings, /v1/company/transcripts, /v1/company/stock_prices/intraday, /v1/company/logo, /v1/politician_trades, /v1/fund_letters) with the reason and alternatives in error.details. ### news, filing_search and coverage tools (mcp) - news: 8-K news across all companies with importance; filing_search: keyword search over EDGAR documents; coverage: what FinancialMD serves and does not (consensus estimates, transcripts, real-time prices and other licensed data are named as not covered, with alternatives). company_events takes importance_min. ## 2026-11-12 ### Tell us what data you need (api) - POST /v1/request-data takes { kind, want, why?, company?, endpoint_or_tool? }: free, keyless, never charged, reviewed weekly. GET /v1/request-data describes the body. - unknown_company, not_covered, unknown_concept, an unknown ratio and an unknown /v1/ route answer with a request_data remedy; an empty search or screen carries one in meta.remedies. - A ticker= query parameter is read as company= when company= is absent. An unknown_company remedy names the directory search for the value. - MCP tool request_data does the same from an agent. ### One price sheet for the agent host (planned, not charged) (api) - Planned per-call prices on agent.financial.md: standardized statements and ratios $0.005 ($0.002 from a funded key), verify $0.02, KPIs, segments and the screen $0.05. Fields and the filing layer stay free. - Every per-call x402 price is at least $0.005, and answers stay within the $1 default cap of x402 v2 clients. The sheet is in llms.txt, the OpenAPI x-price (with keyed_usd where it differs) and docs/API.md section 6.1. - Nothing is charged today: per-call payment is not switched on. ### Dividends with dates, total return, Form 3 holdings, fund types and fees (api) - GET /v1/company/dividend_events: cash dividends with declaration, record, ex and pay dates as filed and how each was captured; a missing ex-date is never inferred. - GET /v1/company/stock_prices?adjust=total_return adds a dividend-adjusted series beside the split-adjusted one. - GET /v1/company/ownership/insider_holdings serves Form 3, 4 and 5 holding lines; insider holders include them. - GET /v1/fund/profile: a fund's type and ETF flag from N-CEN and each share class's prospectus fees (VOO 0.03 percent). N-PORT holders of a company take period= and read only the newest window. - MCP tools dividends and fund_profile (thirty-two tools in all). ### Company-reported metrics (api) - GET /v1/company/kpis serves adjusted (non-GAAP) measures and operating KPIs read from the companies' own earnings releases and reports, point in time, with a confidence label (high = printed identically in two or more places). - Each value's proof resolves to its citation: accession, document, table, row and value index, character span, raw printed text and the GAAP reconciliation table. Values two documents print differently are withheld and never served. - MCP tool company_kpis (thirty tools in all). ### Delisted and inactive filers, employees, shares per class (api) - Profiles carry listing status (active, delisted with its date, inactive), business address, incorporation country, former names and filing dates from SEC submissions. - GET /v1/screen covers active companies by default; status=delisted|inactive|all opts in. - Profiles carry the newest head count at confidence 0.90 or more with its source sentence, and cover-page shares per share class, never summed. ### Share classes, names, foreign filers and speed (api) - A ticker naming one share class (BRK-A) is served as that listing on prices and valuation, never swapped for another; meta.company.listing names it. - Name search matches common and Chinese names of widely held companies; the MCP company_lookup falls back to a name search when a word is not a ticker. - country is no longer US for foreign filers whose country is not stored (null, or CA for Canadian provinces); a missing fiscal year end comes from the latest annual report. - Faster: filing lookups by accession, 13F holders and holdings, and screens (ten-minute universe window, warmed at its start). ### Split-aware valuation, screening on multiples, capital ratios (api) - Valuation ratios put share counts on the close's basis with confirmed splits (share_adjustment on the value); only unexplained split-sized moves withhold a point. - GET /v1/screen filters and sorts on market_cap, pe_ttm, ev_ebitda_ttm and the other valuation ids. - net_interest_margin is renamed nii_to_avg_loans_securities: net interest income over average net loans plus securities, which is not a bank's reported NIM (docs/ratios.md). CET1, tier 1 and tier 1 leverage ratios as filed in XBRL. - Proof ids of segment facts, N-PORT values and calendar events resolve at GET /proof/{id}. Listings OpenFIGI types as ADR are not priced. - Segments carry the filer's exact period_start and period_end (the SEC data sets round dates to month ends), with period_exact and fsds_period_end. ## 2026-11-11 ### Valuation ratios on IEX closes (api) - GET /v1/company/ratios adds market_cap, enterprise_value, pe_ttm, ps_ttm, pb, ev_ebitda_ttm, ev_ebit_ttm, fcf_yield and dividend_yield, priced at the last IEX close on or before each period end. - GET /v1/company/ratios/daily/{ratio_id} serves a valuation ratio one point per session, each using the facts known that evening. - Every valuation value lists the close's proof first in proof.inputs; GET /proof/{id} recomputes it. data.price_basis says which listing was used and why a company is not priced (several share classes, an ADR, no prices). - Bank ratios (net_interest_margin, efficiency_ratio, loans_to_deposits) and insurer ratios (loss_ratio, acquisition_cost_ratio). ### OAuth 2.1 for MCP connectors (api) - RFC 8414 metadata at /.well-known/oauth-authorization-server; dynamic client registration, Client ID Metadata Documents, PKCE (S256), refresh-token rotation, revocation. - Tokens carry the keyless daily limits in an allowance of their own. No account, no payment. - GET /v1/me reports key.audience, key.expires_at and tier. ### Share-class tickers in any spelling (api) - BRK.B, BRK-B, BRK/B and brk-b resolve to one listing; a bare root such as BRK resolves to the company whose class listings it names. ### Ten new tools and 26 skills (mcp) - New tools: ratios_daily, corporate_actions, events_calendar, company_events, segments, insider_holders, fund_holders, fund_holdings, identifiers, filing_document (twenty-nine in all); stock_prices takes adjust "splits". - 26 task skills under /skills/, all of them in one /skills.zip. ### Splits, dividends, calendar, 8-K events, segments, insider holders, funds, identifiers (api) - New routes: /v1/company/splits, /v1/company/dividends, /v1/events_calendar, /v1/company/events, /v1/company/segments, /v1/company/ownership/insider_holders, /v1/company/ownership/funds, /v1/funds, /v1/fund/holdings, /v1/company/identifiers. - GET /v1/company/stock_prices?adjust=splits adds split-adjusted values (confirmed splits only). ### Filing documents; derivation in proofs (api) - GET /v1/filing/{accession}/document links a filing's EDGAR pages; format=html serves the primary document. - Proofs of derived values (Q4, LTM, formula lines) list every as-reported fact with its weight and a sum check. - GET /v1/company/metrics lists the concepts each template shows, so a bank's list matches its statements. ### Reference pages (docs) - Swagger UI at /docs, the whole reference in one file at /llms-full.txt, and this changelog at /changelog. ## 2026-11-10 ### Daily prices from IEX (api) - GET /v1/company/stock_prices serves daily bars built from trades at IEX only, with the venue's citation in meta.attribution and a proof per number. ### Ownership (api) - Insider transactions (Forms 3, 4, 5), institutional holders of a company and a manager's holdings (Form 13F), with proofs back to each form. ### Classification (api) - Profiles say where sector and industry come from: the filer's SIC code in its EDGAR submissions document. ## 2026-11-09 ### Screen, filing facts and the supplemental statement (api) - GET /v1/screen filters and sorts every covered company on latest-period metrics. - GET /v1/filing/{accession}/facts returns every mapped fact a filing tagged, by statement. - Share counts and per-share figures in /v1/company/financials/supplemental/standardized; sector and industry on company lists. ## 2026-11-08 ### Version 1 (api) - Standardized and as-reported statements with proofs, point-in-time reads (as_of, original, history), ratios, verify, proofs, the changes feed, and the discovery files.