curl --request GET \
--url https://api.financialdatasets.ai/macro/gdp \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/macro/gdp"
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/macro/gdp', 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/macro/gdp",
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/macro/gdp"
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/macro/gdp")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/macro/gdp")
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{
"gdp": [
{
"series": "<string>",
"date": "<string>",
"value": 123,
"change_prior": 123,
"change_year": 123,
"change_year_pct": 123
}
],
"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."
}{
"error": "Not Found",
"message": "Ticker XXXX not found"
}GDP Data API
US GDP and income history in 12 series: real GDP growth from 1947, real and nominal GDP, the four contributions to growth, income-side growth, corporate profits, personal income, the saving rate, and real consumer spending, with the change from the prior period and from a year earlier.
curl --request GET \
--url https://api.financialdatasets.ai/macro/gdp \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/macro/gdp"
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/macro/gdp', 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/macro/gdp",
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/macro/gdp"
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/macro/gdp")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/macro/gdp")
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{
"gdp": [
{
"series": "<string>",
"date": "<string>",
"value": 123,
"change_prior": 123,
"change_year": 123,
"change_year_pct": 123
}
],
"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."
}{
"error": "Not Found",
"message": "Ticker XXXX not found"
}Overview
The Financial Datasets GDP API returns one US growth or income series per request: real GDP growth, the real and nominal level of GDP, the four contributions to growth, income-side growth (GDI), corporate profits, personal income, the saving rate, and real consumer spending, with the change from the prior period and from a year earlier computed for you. It covers 12 series from 1947 to today, updated within minutes of each release. The quarterly series start in 1947, personal income and the saving rate in 1959, and real consumer spending in 2007. The data comes directly from authoritative government sources (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, or pay per request with x402. Pricing starts at $20. Values are in each series’ own units (percent, percentage points, billions of dollars); the changes are in the same units, plus a percent change over the year for dollar series. To get started, please create an account and grab your API key at financialdatasets.ai. You will use the API key to authenticate your API requests.Coverage
| History | Series | Updated |
|---|---|---|
| 1947 to today | 12 | Quarterly and monthly |
Series
Every series is seasonally adjusted. Quarterly (date is the first day of the quarter):
| Series | What it is | Units | From |
|---|---|---|---|
real_gdp_growth | Real GDP, percent change from the preceding quarter, annual rate | Percent | 1947 |
real_gdp | Real GDP, annual rate | Billions of chained 2017 dollars | 1947 |
nominal_gdp | GDP in current dollars, annual rate | Billions of dollars | 1947 |
consumer_spending_contribution | Contribution of consumer spending to real GDP growth | Percentage points | 1947 |
investment_contribution | Contribution of private investment to real GDP growth | Percentage points | 1947 |
net_exports_contribution | Contribution of net exports to real GDP growth | Percentage points | 1947 |
government_contribution | Contribution of government spending and investment to real GDP growth | Percentage points | 1947 |
real_gdi_growth | Real gross domestic income, percent change from the preceding quarter, annual rate | Percent | 1947 |
corporate_profits | Corporate profits with inventory valuation and capital consumption adjustments, annual rate | Billions of dollars | 1947 |
date is the first day of the month):
| Series | What it is | Units | From |
|---|---|---|---|
personal_income | Personal income, annual rate | Billions of dollars | 1959 |
saving_rate | Personal saving as a percentage of disposable personal income | Percent | 1959 |
real_consumer_spending | Real personal consumption expenditures, annual rate | Billions of chained 2017 dollars | 2007 |
GET request to:
https://api.financialdatasets.ai/macro/gdp/series/
Reading the fields
dateis the reference period, not the release date: the first day of the quarter for quarterly series (2026-07-01is the third quarter of 2026, first published in late October) and the first day of the month for monthly series.valueis the published figure in the series’ units. Dollar series are in billions at a seasonally adjusted annual rate. The growth rates are quarter over quarter at an annual rate.- The four contributions are in percentage points and add up to
real_gdp_growth, within rounding. change_priorisvalueminus the prior period’s value: the prior quarter for quarterly series, the prior month for monthly. Same units asvalue.change_yearisvalueminus the value one year earlier: the same quarter or month a year back. Same units asvalue.change_year_pctischange_yearas a percent of the year-earlier value, rounded to one decimal. Forreal_gdpit is the year-over-year growth rate. It isnullfor series measured in percent or percentage points: their change is stated in points, inchange_year.- A change is
nullwhen the comparison period was not published. - Each quarter is estimated three times, about a month apart (advance, second, third). History holds the latest published values: each estimate replaces the one before it.
real_gdi_growthandcorporate_profitsare published with a later estimate of a quarter than the other quarterly series, so their newest row can be one quarter behind.
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
seriesparameter, which is required. Optionally addstart_dateandend_date(inclusive,YYYY-MM-DD). Any day inside a quarter or month selects that period. With no dates you get the trailing five years. - Execute the API request.
next_page_url; request it as-is to get the next page. See the pagination guide.
Example
import requests
# add your API key to the headers
headers = {
"X-API-KEY": "your_api_key_here"
}
# set parameters
series = 'real_gdp_growth' # required
start_date = '2025-07-01' # optional
end_date = '2026-09-30' # optional
# create the URL with parameters
url = (
f'https://api.financialdatasets.ai/macro/gdp'
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
gdp = response.json().get('gdp')
Example Response
{
"gdp": [
{
"series": "real_gdp_growth",
"date": "2026-07-01",
"value": 3.4,
"change_prior": 1.2,
"change_year": -0.5,
"change_year_pct": null
},
{
"series": "real_gdp_growth",
"date": "2026-04-01",
"value": 2.2,
"change_prior": -0.3,
"change_year": -1.8,
"change_year_pct": null
}
]
}
FAQ
Is date the release date?
No. date is the reference period. For quarterly series it is the first day of the quarter: 2026-07-01 is the third quarter of 2026, first published in late October. For monthly series it is the first day of the month.
Are the three estimates of a quarter included?
History holds the latest published values. Each quarter is estimated three times, about a month apart, and each estimate replaces the stored values. To receive each estimate as it is published, subscribe to thegdp.created webhook.
How do I get year-over-year GDP growth?
Requestreal_gdp and read change_year_pct. real_gdp_growth is the quarter-over-quarter rate at an annual rate, the headline number of each release.
Why is change_year_pct null for some series?
It is null for series measured in percent or percentage points. A rate’s change is stated in points, in change_year.
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 series id, e.g. real_gdp_growth. Nine quarterly series (real_gdp_growth, real_gdp, nominal_gdp, consumer_spending_contribution, investment_contribution, net_exports_contribution, government_contribution, real_gdi_growth, corporate_profits) and three monthly ones (personal_income, saving_rate, real_consumer_spending), all seasonally adjusted. Use the /macro/gdp/series endpoint to get the list.
The first period to return, inclusive, in YYYY-MM-DD format; any day inside a quarter or month selects that period. Defaults to five years before end_date when both dates are omitted; omit it with an end_date to get all available history through that date.
The last period to return, inclusive, in YYYY-MM-DD format. Defaults to today.
Opaque 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.