Query GDP, regional income, international trade, and industry economic data from the Bureau of Economic Analysis (BEA) API. Use when the user asks about GDP by industry for mining or oil and gas, regional personal income in energy-producing counties, trade in petroleum or lithium, gross output of extraction, value added by mining, or economic impact of oil and gas on state economies. Trigger phrases: "GDP from oil and gas extraction", "mining share of GDP", "personal income Monongalia County WV", "regional economic impact drilling", "trade in lithium", "petroleum trade balance", "gross output mining", "value added extraction", "natural gas contribution WV economy", "per capita income energy counties", "BEA regional data". Produces economic tables and narrative analysis with industry and regional context.
Fetches and analyzes U.S. economic accounts data from the Bureau of Economic Analysis (BEA) API. Covers GDP by industry, regional personal income, international trade, and input-output accounts. Essential for understanding the economic context of petroleum-producing regions and the mining/extraction sector.
An API key is required. Free registration.
Resolution order (stop at first success):
~/.config/bea/credentials -- parse api_key=<value> from this fileBEA_API_KEY env var -- fallback if credentials file is absent~/.config/bea/credentials
as api_key=YOUR_KEY (chmod 600)."Never hardcode or log the key. Pass it as a query parameter .
&UserID=<KEY>Reading the credentials file (bash):
KEY=$(grep '^api_key=' ~/.config/bea/credentials 2>/dev/null | cut -d= -f2)
[ -z "$KEY" ] && KEY="${BEA_API_KEY}"
if [ -z "$KEY" ]; then
echo "No BEA API key found. Get one free at https://apps.bea.gov/API/signup/"
echo "Store in ~/.config/bea/credentials as api_key=YOUR_KEY"
exit 1
fi
Reading the credentials file (Go):
func resolveAPIKey() (string, error) {
home, _ := os.UserHomeDir()
creds := filepath.Join(home, ".config", "bea", "credentials")
if data, err := os.ReadFile(creds); err == nil {
for _, line := range strings.Split(string(data), "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "api_key=") {
return strings.TrimPrefix(line, "api_key="), nil
}
}
}
if key := os.Getenv("BEA_API_KEY"); key != "" {
return key, nil
}
return "", fmt.Errorf("no BEA API key found; register free at https://apps.bea.gov/API/signup/")
}
Base URL: https://apps.bea.gov/api/data/
All requests use GET with query parameters. Every request requires:
UserID -- your API keymethod -- the API method to callResultFormat -- always use JSON| Method | Purpose |
|---|---|
GetDataSetList | List all available datasets |
GetParameterList | List parameters for a dataset |
GetParameterValues | List valid values for a parameter |
GetParameterValuesFiltered | Filtered parameter values |
GetData | Fetch actual data |
| DatasetName | Description | Key Use |
|---|---|---|
GDPByIndustry | GDP, value added, gross output by NAICS industry | Mining/extraction share of GDP |
Regional | Personal income, employment, GDP by state/county/MSA | Energy county economics |
ITA | International Transactions (trade) | Petroleum/lithium trade flows |
IntlServTrade | International services trade | Oilfield services trade |
NIPA | National Income and Product Accounts | National-level aggregates |
InputOutput | Input-output tables | Industry supply chain analysis |
# GDP by industry -- Mining sector (NAICS 21)
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=GDPByIndustry&\
TableID=1&\
Frequency=A&\
Year=2018,2019,2020,2021,2022,2023&\
Industry=21&\
ResultFormat=JSON"
Key Industry codes for PNGE:
| Industry Code | Description |
|---|---|
21 | Mining (includes oil/gas, minerals, coal) |
211 | Oil and Gas Extraction |
212 | Mining (except oil and gas) -- includes lithium mining |
213 | Support Activities for Mining |
ALL | All industries (for computing shares) |
Table IDs for GDPByIndustry:
| TableID | Measure |
|---|---|
1 | Value Added by Industry (nominal) |
5 | Value Added by Industry (real, chained dollars) |
6 | Value Added by Industry (quantity index) |
7 | Gross Output by Industry (nominal) |
11 | Gross Output by Industry (real, chained dollars) |
25 | Value Added by Industry as % of GDP |
# Per capita personal income for WV counties
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=Regional&\
TableName=CAINC1&\
GeoFips=COUNTY&\
LineCode=3&\
Year=2022&\
ResultFormat=JSON"
Key Regional tables:
| TableName | Description |
|---|---|
CAINC1 | Personal Income Summary (county, state, MSA) |
CAINC4 | Personal Income and Employment by Major Component |
CAINC5N | Personal Income by Major Component and Earnings by NAICS |
CAINC30 | Economic Profile (summary of key indicators) |
CAGDP1 | GDP Summary by county (limited industries) |
CAGDP2 | GDP by Industry at county level |
CAGDP9 | Real GDP by county |
SAINC1 | State Personal Income Summary |
SAGDP2N | GDP by State and Industry |
GeoFips codes:
| Code | Scope |
|---|---|
STATE | All states |
COUNTY | All counties |
MSA | All metro/micro areas |
54000 | West Virginia (state FIPS) |
54061 | Monongalia County, WV |
54049 | Marion County, WV |
42125 | Washington County, PA |
39013 | Belmont County, OH |
LineCode values for CAINC1:
| LineCode | Measure |
|---|---|
1 | Personal income (thousands of dollars) |
2 | Population |
3 | Per capita personal income (dollars) |
# International trade in goods -- petroleum category
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=ITA&\
Indicator=BalGds&\
AreaOrCountry=AllCountries&\
Frequency=A&\
Year=2020,2021,2022,2023&\
ResultFormat=JSON"
Key ITA indicators:
| Indicator | Description |
|---|---|
ExpGds | Exports of goods |
ImpGds | Imports of goods |
BalGds | Balance on goods |
ExpGdsEndUse | Exports by end-use category |
ImpGdsEndUse | Imports by end-use category |
Map the user's question to dataset and parameters:
| User Wants | Dataset | Parameters |
|---|---|---|
| Mining share of GDP | GDPByIndustry | Industry=21, TableID=25 |
| Oil/gas extraction GDP | GDPByIndustry | Industry=211, TableID=1 |
| WV county income | Regional | TableName=CAINC1, GeoFips=54000 or specific county |
| Income in drilling counties | Regional | TableName=CAINC5N + mining earnings line |
| Petroleum trade balance | ITA | Indicator=BalGds |
| Mining employment by state | Regional | TableName=CAEMP25N |
If unsure of valid parameter values, query metadata first:
# List valid industries for GDPByIndustry
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetParameterValues&\
DatasetName=GDPByIndustry&\
ParameterName=Industry&\
ResultFormat=JSON"
# List valid tables for Regional dataset
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetParameterValues&\
DatasetName=Regional&\
ParameterName=TableName&\
ResultFormat=JSON"
Build the URL with appropriate parameters. Default behavior:
Frequency=A (annual) unless quarterly data is neededResultFormat=JSON always# Value added by oil and gas extraction as % of GDP
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=GDPByIndustry&\
TableID=25&\
Frequency=A&\
Year=2018,2019,2020,2021,2022,2023&\
Industry=211&\
ResultFormat=JSON"
Response structure:
{
"BEAAPI": {
"Request": {
"RequestParam": [...]
},
"Results": {
"Statistic": "Value Added by Industry as a Percentage of GDP",
"UTCProductionTime": "2024-11-15T12:30:00.000",
"Dimensions": [...],
"Data": [
{
"TableID": "25",
"Frequency": "A",
"Year": "2023",
"Quarter": null,
"Industry": "211",
"IndustrYDescription": "Oil and gas extraction",
"DataValue": "1.3",
"NoteRef": ""
}
],
"Notes": [...]
}
}
}
Key fields:
BEAAPI.Results.Data[] -- array of data recordsDataValue -- string, parse to float; may be "(D)" for suppressed dataNoteRef -- footnote reference code (check Notes array)Year/Quarter -- time periodSpecial values in DataValue:
"(D)" -- data suppressed to avoid disclosure of individual firms"(NA)" -- not available"(NM)" -- not meaningfulFormat: Data Table + Narrative
Present a markdown table of the most relevant rows (cap at ~20 rows), then a narrative summary covering:
Example output structure:
## Oil and Gas Extraction -- Value Added as % of GDP (2018-2023)
| Year | Oil/Gas Extraction (% GDP) | All Mining (% GDP) |
|------|----------------------------|--------------------|
| 2023 | 1.3 | 1.9 |
| 2022 | 2.1 | 2.8 |
| 2021 | 1.2 | 1.7 |
| 2020 | 0.7 | 1.1 |
| 2019 | 1.5 | 2.0 |
| 2018 | 1.7 | 2.2 |
**Summary:** Oil and gas extraction contributed 1.3% of U.S. GDP in 2023,
down from its post-COVID rebound peak of 2.1% in 2022 when high commodity
prices inflated the sector's nominal value added. The 2020 trough (0.7%)
reflects the COVID demand destruction. For WV specifically, the mining
sector's GDP share is significantly higher -- use the Regional dataset
(SAGDP2N) for state-level industry breakdown.
*Source: BEA GDP by Industry accounts. Nominal value added.*
The BEA API does not paginate -- it returns all matching data in a single response. For large result sets (e.g., all counties), the response may be large but complete.
If a request returns too many records (e.g., all counties x all years), narrow the query by specifying GeoFips codes or limiting the year range.
| Condition | Meaning | Action |
|---|---|---|
"Error" key in response | API error | Read ErrorDetail.Description for message |
"APIErrorCode": "40" | Invalid parameter value | Use GetParameterValues to find valid options |
"APIErrorCode": "36" | Missing required parameter | Check required params for the dataset |
"APIErrorCode": "24" | Invalid UserID | Verify API key is correct |
| HTTP 503 | Service unavailable | Retry after 5 seconds (max 3 retries) |
DataValue: "(D)" | Suppressed for disclosure | Data exists but cannot be shown; try broader geography |
DataValue: "(NA)" | Not available | Data not produced for this combination |
Common error response:
{
"BEAAPI": {
"Request": {...},
"Results": {
"Error": {
"APIErrorCode": "40",
"APIErrorDescription": "The parameter value '999' is not valid..."
}
}
}
}
# Per capita income for key Marcellus/Utica counties
# Monongalia WV, Marion WV, Washington PA, Belmont OH
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=Regional&\
TableName=CAINC1&\
GeoFips=54061,54049,42125,39013&\
LineCode=3&\
Year=2018,2019,2020,2021,2022&\
ResultFormat=JSON"
# Earnings by NAICS industry for WV counties
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=Regional&\
TableName=CAINC5N&\
GeoFips=54061&\
LineCode=200&\
Year=2022&\
ResultFormat=JSON"
LineCode 200 = Mining, quarrying, and oil and gas extraction earnings.
# GDP by industry for West Virginia
curl -s "https://apps.bea.gov/api/data/?\
UserID=$KEY&\
method=GetData&\
DatasetName=Regional&\
TableName=SAGDP2N&\
GeoFips=54000&\
LineCode=6&\
Year=2022&\
ResultFormat=JSON"
LineCode 6 = Mining, quarrying, and oil and gas extraction.
| FIPS | County | State | Notes |
|---|---|---|---|
| 54061 | Monongalia | WV | Marcellus core, university town |
| 54049 | Marion | WV | Marcellus core, coal heritage |
| 54051 | Marshall | WV | Marcellus core, Ohio River |
| 54009 | Brooke | WV | Northern panhandle |
| 54029 | Hancock | WV | Northern panhandle |
| 54103 | Wetzel | WV | Major Marcellus producer |
| 42125 | Washington | PA | SW PA Marcellus core |
| 42059 | Greene | PA | Major Marcellus producer |
| 39013 | Belmont | OH | Utica core |
| 39111 | Monroe | OH | Utica core |
(D) to protect individual firm confidentiality. Mining data
is especially prone to this in counties with few operators.bash with curl + jq for API calls(D), (NA), (NM) as missing dataALL for all
available years. LAST5 returns the last 5 years.XX000 (e.g., 54000 for WV). County codes
are 5-digit FIPS. Use STATE, COUNTY, or MSA for all entities of
that type.Industry=ALL or comma-separated codes.
At the county level, only broad industry groups are available.