Financial Literature

US Bureau of Economic Analysis

BEA API — GDP, PCE and personal income from the agency that compiles the national accounts

When the question is about the national accounts themselves — GDP and its components, PCE prices, personal income and saving — and you want the table BEA publishes rather than a single headline mirrored elsewhere.

macropricesUnited States
Asset classesmacro · prices
Frequencymonthly → annual
History1947 → today
Limit · costFree key · 100 requests/min, 100 MB/min
KeyFree key needed — Register an email at apps.bea.gov/api/signup/ — the key arrives by mail within minutes.
Formats · pull withjson · xml · csv — python, excel
LicenceUS government work, public domain. Cite BEA, the table and the vintage date.
RedistributeYes, with attribution
Best for“What was real GDP growth last quarter, by component?” · “PCE inflation — the Fed's preferred gauge”
When to use it

Reach for it when…

When the question is about the national accounts themselves — GDP and its components, PCE prices, personal income and saving — and you want the table BEA publishes rather than a single headline mirrored elsewhere.

Not for: Anything outside the national accounts; quick single-series pulls (FRED has GDPC1 and PCEPI with no key).

How to read it

Units, revisions, traps

Units. Growth rates are seasonally adjusted annualised rates (SAAR): a quarter's change compounded to a year. Levels are chained 2017 dollars for real series.

Revisions. Three estimates per quarter (advance, second, third) then annual and comprehensive revisions; the 'advance' print is the one markets trade on and the least reliable.

  • Line numbers, not names, identify series inside a table — T10101 line 1 is real GDP.
  • Frequency Q returns quarters as 2026Q2; parse before sorting.
  • PCE and CPI weight shelter differently; PCE inflation runs about half a point below CPI.

Classic mistake: Multiplying a quarterly SAAR growth rate by four.

How to use it in your own work

Three recipes

Each recipe: Python · Excel · Sheets, with how to read the result. Python recipes run under pandas; recipe 1 is re-run by the weekly check where the source allows it.

How to use it in your own work

Copy the snippet, change the series id, read the result the way the footer says. Replace YOUR_…_KEY with your own key where one is needed.

Recipe 1Real GDP growth by quarter (SAAR)

# T10101 line 1 = real GDP, percent change from preceding period, annualised
import requests, pandas as pd
KEY = "YOUR_BEA_KEY"
u = ("https://apps.bea.gov/api/data/?&UserID=" + KEY + "&method=GetData&DataSetName=NIPA"
     "&TableName=T10101&Frequency=Q&Year=ALL&ResultFormat=JSON")
rows = requests.get(u, timeout=60).json()["BEAAPI"]["Results"]["Data"]
df = pd.DataFrame(rows)
gdp = df[df.LineNumber == "1"].set_index("TimePeriod")["DataValue"].astype(float)
print(gdp.tail(8))
How to read the resultEach value is an annualised quarterly growth rate. Two negative quarters is a rule of thumb, not the NBER's definition of recession.

Recipe 2PCE price index, the Fed's gauge

# T20804 = PCE price indexes, monthly; line 1 headline, line 25 core (ex food and energy)
import requests, pandas as pd
KEY = "YOUR_BEA_KEY"
u = ("https://apps.bea.gov/api/data/?&UserID=" + KEY + "&method=GetData&DataSetName=NIPA"
     "&TableName=T20804&Frequency=M&Year=ALL&ResultFormat=JSON")
df = pd.DataFrame(requests.get(u, timeout=60).json()["BEAAPI"]["Results"]["Data"])
pce = df[df.LineNumber == "1"].set_index("TimePeriod")["DataValue"].astype(float)
pce.index = pd.to_datetime(pce.index, format="%YM%m")
print((pce.pct_change(12) * 100).dropna().tail(6).round(2))
How to read the resultCore PCE (line 25) is the series the Fed's 2% target refers to. It is released at the end of the month, about two weeks after CPI.

Recipe 3Personal saving rate

# T20100 line 35 = personal saving as a percent of disposable income
import requests, pandas as pd
KEY = "YOUR_BEA_KEY"
u = ("https://apps.bea.gov/api/data/?&UserID=" + KEY + "&method=GetData&DataSetName=NIPA"
     "&TableName=T20100&Frequency=M&Year=ALL&ResultFormat=JSON")
df = pd.DataFrame(requests.get(u, timeout=60).json()["BEAAPI"]["Results"]["Data"])
save = df[df.LineDescription.str.contains("Personal saving as a percentage", na=False)].set_index("TimePeriod")["DataValue"].astype(float)
print(save.tail(6))
How to read the resultA falling saving rate with flat income means households are spending from savings — it flatters consumption for a while.

Series → question map

The ids we use from BEA API, each with the question it answers. The catalog's compare view reads the concept tags behind these rows.

SeriesAnswersRegionConcept
T10101 line 1Is the US economy growing? (real GDP, SAAR)United Statesgdp
T20804 line 1 / 25PCE, the Fed's preferred measureWhat is PCE inflation, headline and core?United Statescpi
T20100 line 35Are households saving or spending down?United Statessaving

Compare with

Same question, different source: FRED, BLS API, Eurostat API. The compare view lines up coverage, frequency, history and access side by side and lists what the combination makes possible.

Open compare: BEA API · FRED · BLS API →

Questions readers ask

Do I need a key for BEA?

For the API, yes — free, by email, in minutes. The interactive tables on bea.gov download as CSV without one.

Why three GDP numbers for the same quarter?

Advance, second and third estimates a month apart as more source data arrives; then annual revisions. Say which vintage you are quoting.

PCE or CPI?

CPI is what households feel and what most contracts index to; PCE is what the Fed targets and weights shelter less. Both are on this card's sister sources.

From the paper

Educational only — we explain, we never advise · snippet licence: public domain · corrections to [email protected], fixed within a day and logged in the changelog.