curl --request GET \
--url https://api.financialdatasets.ai/kpi/metrics \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/kpi/metrics"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.financialdatasets.ai/kpi/metrics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.financialdatasets.ai/kpi/metrics",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.financialdatasets.ai/kpi/metrics"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.financialdatasets.ai/kpi/metrics")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/kpi/metrics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"kpi_metrics": [
{
"ticker": "DAL",
"metric_name": "load_factor",
"value": 82,
"unit": "%",
"period": "Q4 2025",
"period_type": "quarterly",
"segment": "Commercial Engines & Services",
"yoy_value": 84,
"yoy_change_pct": -2.381,
"source_text": "Passenger load factor",
"source_url": "https://www.sec.gov/Archives/edgar/data/27904/000002790426000008/deltaairlinesannouncesdece.htm"
}
],
"next_page_url": "<string>"
}{
"error": "Bad Request",
"message": "Invalid request parameters"
}{
"error": "Unauthorized",
"message": "Invalid API key provided"
}{
"error": "Payment Required",
"message": "This endpoint requires a paid subscription. Please upgrade your plan."
}Company KPI Data API
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.
curl --request GET \
--url https://api.financialdatasets.ai/kpi/metrics \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/kpi/metrics"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.financialdatasets.ai/kpi/metrics', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.financialdatasets.ai/kpi/metrics",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.financialdatasets.ai/kpi/metrics"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.financialdatasets.ai/kpi/metrics")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/kpi/metrics")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"kpi_metrics": [
{
"ticker": "DAL",
"metric_name": "load_factor",
"value": 82,
"unit": "%",
"period": "Q4 2025",
"period_type": "quarterly",
"segment": "Commercial Engines & Services",
"yoy_value": 84,
"yoy_change_pct": -2.381,
"source_text": "Passenger load factor",
"source_url": "https://www.sec.gov/Archives/edgar/data/27904/000002790426000008/deltaairlinesannouncesdece.htm"
}
],
"next_page_url": "<string>"
}{
"error": "Bad Request",
"message": "Invalid request parameters"
}{
"error": "Unauthorized",
"message": "Invalid API key provided"
}{
"error": "Payment Required",
"message": "This endpoint requires a paid subscription. Please upgrade your plan."
}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, or pay per request with x402. 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
Coverage
| Tickers | Years of Coverage | Updated |
|---|---|---|
| 600+ | 3+ years | Within 30 seconds |
Available Tickers
You can fetch a list of available tickers with aGET request to:
https://api.financialdatasets.ai/kpi/metrics/tickers/
Available Sectors
You can fetch a list of available sectors with aGET request to:
https://api.financialdatasets.ai/kpi/metrics/sectors/
Getting Started
There are only 3 steps for making a successful API call:- Add your API key to the header of the request as
X-API-KEY. - Add the required query param
ticker. - 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
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
{
"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_urllinks 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 includessource_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 returns forward guidance from earnings releases as ranges, point estimates, or directional signals. Non-GAAP Metrics 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. An agent with a wallet can also pay per request with x402, with no account.Authorizations
API key for authentication.
Query Parameters
The ticker symbol.
Filter to a specific metric (e.g., load_factor, cet1_ratio).
Filter by period type: quarterly or annual.
quarterly, annual Only return metrics on or after this date (YYYY-MM-DD).
Only return metrics on or before this date (YYYY-MM-DD).
Number of periods to return. Returns all metrics for the N most recent periods. This is the total across all pages, not a page size: each page holds up to 10 records, linked by next_page_url.
x <= 50Opaque pagination cursor from a previous response's next_page_url. When provided, all other query parameters are ignored: the cursor carries the original request's filters. Treat it as opaque; do not construct or modify it.