The EODHD Commodities API provides historical price data for 23 commodity series sourced from the Federal Reserve Economic Data (FRED). It covers energy, metals, and agricultural commodities with daily, weekly, monthly, quarterly, and annual intervals — going back decades for most series.
All code examples use Python. You will need an EODHD API subscription that includes access to the Commodities endpoint.
Quick jump:
Known Limitations
- Precious metals removed: Gold (LBMA), Silver, Platinum, and Palladium series have been discontinued by FRED due to LBMA licensing changes.
- Monthly lag: Monthly series (metals, agricultural) typically have a 1-2 month reporting delay from FRED.
- Interval availability: Not all commodities support all intervals. Daily data is only available for energy commodities. Metals and agricultural commodities are typically monthly only.
API Endpoint
https://eodhd.com/api/commodities/historical/{CODE}?api_token=YOUR_TOKEN
curl --location "https://eodhd.com/api/commodities/historical/{CODE}?api_token=YOUR_TOKEN&fmt=json"
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://eodhd.com/api/commodities/historical/{CODE}?api_token=YOUR_TOKEN&fmt=json',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'GET',
));
$data = curl_exec($curl);
curl_close($curl);
try {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
var_dump($data);
} catch (Exception $e) {
echo 'Error. '.$e->getMessage();
}
import requests
url = f'https://eodhd.com/api/commodities/historical/{CODE}?api_token=YOUR_TOKEN&fmt=json'
data = requests.get(url).json()
print(data)
library(httr)
library(jsonlite)
url <- 'https://eodhd.com/api/commodities/historical/{CODE}?api_token=YOUR_TOKEN&fmt=json'
response <- GET(url)
if (http_type(response) == "application/json") {
content <- content(response, "text", encoding = "UTF-8")
cat(content)
} else {
cat("Error while receiving data\n")
}
Try it now (it's free)!
How to use it (YouTube)
Parameters:
| Parameter | Required | Description |
|---|---|---|
| CODE | Yes | Commodity code (e.g., WTI, BRENT, URANIUM) or ALL_COMMODITIES for the global index |
| api_token | Yes | Your EODHD API token |
| fmt | No | Response format: json (default) or csv |
| interval | No | Data frequency: daily, weekly, monthly (default), quarterly, annual |
Response Format
The API returns a JSON object with three sections: meta (commodity metadata), data (price history), and links (pagination).
{
"meta": {
"name": "US Regular All Formulations Gas Price",
"interval": "monthly",
"unit": "Dollars per Gallon",
"offset": 0,
"limit": 1000,
"total": 13
},
"data": [
{"date": "2026-03-01", "value": 3.99},
{"date": "2026-02-01", "value": 2.937},
{"date": "2026-01-01", "value": 2.853}
],
"links": {
"next": null
}
}
| Field | Type | Description |
|---|---|---|
| meta.name | string | Full commodity name from FRED |
| meta.interval | string | Data frequency (daily, weekly, monthly, quarterly, annual) |
| meta.unit | string | Measurement unit (e.g., Dollars per Barrel, Index 2016 = 100) |
| meta.total | integer | Total number of data points available |
| data[].date | string | Date in YYYY-MM-DD format |
| data[].value | number | Price or index value |
Available Commodities
The API covers 23 commodity series across three categories:
Energy (10 series)
| Code | Name | Unit | Frequency |
|---|---|---|---|
| WTI | Crude Oil WTI (Cushing, Oklahoma) | Dollars per Barrel | Daily |
| BRENT | Crude Oil Brent (Europe) | Dollars per Barrel | Daily |
| NATURAL_GAS | Henry Hub Natural Gas Spot Price | Dollars per Million BTU | Daily |
| GASOLINE_US | US Regular All Formulations Gas Price | Dollars per Gallon | Weekly |
| DIESEL_USGULF | No. 2 Diesel (US Gulf Coast) | Dollars per Gallon | Daily |
| HEATING_OIL_NYH | No. 2 Heating Oil (NY Harbor) | Dollars per Gallon | Daily |
| JET_FUEL_USGULF | Kerosene-Type Jet Fuel (US Gulf Coast) | Dollars per Gallon | Daily |
| PROPANE_MBTX | Propane (Mont Belvieu, Texas) | Dollars per Gallon | Daily |
| COAL_AU | Coal (Australian thermal) | Dollars per Metric Ton | Monthly |
| URANIUM | Uranium (Global Spot Price) | Dollars per Pound | Monthly |
Metals (3 series)
| Code | Name | Unit | Frequency |
|---|---|---|---|
| ALUMINUM | Global Price of Aluminum | Dollars per Metric Ton | Monthly |
| COPPER | Global Price of Copper | Dollars per Metric Ton | Monthly |
| NICKEL | Global Price of Nickel | Dollars per Metric Ton | Monthly |
Agricultural (7 series)
| Code | Name | Unit | Frequency |
|---|---|---|---|
| WHEAT | Global Price of Wheat | Dollars per Metric Ton | Monthly |
| CORN | Global Price of Corn | Dollars per Metric Ton | Monthly |
| SUGAR | Global Price of Sugar | Cents per Pound | Monthly |
| COTTON | Global Price of Cotton | Cents per Pound | Monthly |
| RUBBER | Global Price of Rubber | Dollars per Kilogram | Monthly |
| COFFEE | Global Price of Coffee (Arabica) | Cents per Pound | Monthly |
| SOYBEANS | Global Price of Soybeans | Dollars per Metric Ton | Monthly |
Indices (3 series)
| Code | Name | Unit | Frequency |
|---|---|---|---|
| ALL_COMMODITIES | Global Price Index of All Commodities | Index 2016 = 100 | Monthly |
| ENERGY_INDEX | Energy Price Index | Index 2016 = 100 | Monthly |
| NATGAS_EU | Natural Gas Price (EU) | Dollars per Million BTU | Monthly |
Quick Start: Python
Fetch the latest WTI crude oil prices:
import requests
API_TOKEN = "YOUR_API_TOKEN"
def get_commodity(code, interval="monthly"):
url = f"https://eodhd.com/api/commodities/historical/{code}"
params = {"api_token": API_TOKEN, "fmt": "json", "interval": interval}
response = requests.get(url, params=params)
return response.json()
# Monthly WTI prices
data = get_commodity("WTI")
print(f"Commodity: {data['meta']['name']}")
print(f"Unit: {data['meta']['unit']}")
print(f"Total records: {data['meta']['total']}")
for row in data["data"][:5]:
print(f" {row['date']}: ${row['value']}")
Output:
Commodity: Crude Oil Prices: West Texas Intermediate (WTI) - Cushing, Oklahoma
Unit: Dollars per Barrel
Total records: 13
2026-03-01: $104.69
2026-02-01: $66.96
2026-01-01: $64.5
2025-12-01: $57.26
2025-11-01: $58.58
Using Intervals
The interval parameter controls the data frequency. Available values: daily, weekly, monthly (default), quarterly, annual. Not all intervals are available for every commodity — it depends on the underlying FRED data source.
# Daily WTI prices — much more granular
daily = get_commodity("WTI", interval="daily")
print(f"Daily records: {daily['meta']['total']}")
for row in daily["data"][:5]:
print(f" {row['date']}: ${row['value']}")
Output:
Daily records: 249
2026-03-30: $104.69
2026-03-27: $101.26
2026-03-26: $96.18
2026-03-25: $95.82
2026-03-24: $93.26
Building a Commodity Dashboard
Fetch multiple commodities and compare their recent performance:
import requests
API_TOKEN = "YOUR_API_TOKEN"
def get_commodity(code, interval="monthly"):
url = f"https://eodhd.com/api/commodities/historical/{code}"
params = {"api_token": API_TOKEN, "fmt": "json", "interval": interval}
return requests.get(url, params=params).json()
commodities = ["WTI", "BRENT", "NATURAL_GAS", "ALUMINUM", "COPPER", "WHEAT"]
print(f"{'Code':<15} {'Name':<45} {'Latest':>10} {'Unit':<25}")
print("-" * 100)
for code in commodities:
data = get_commodity(code)
meta = data["meta"]
latest = data["data"][0] if data["data"] else None
print(f"{code:<15} {meta['name'][:44]:<45} "
f"{'$' + str(latest['value']) if latest else 'N/A':>10} "
f"{meta['unit']:<25}")
Output:
Code Name Latest Unit
--------------------------------------------------------------------------
WTI Crude Oil Prices: West Texas Intermediate $104.69 Dollars per Barrel
BRENT Crude Oil Prices: Brent - Europe $99.33 Dollars per Barrel
NATURAL_GAS Henry Hub Natural Gas Spot Price $4.38 Dollars per Million BTU
ALUMINUM Global Price of Aluminum $2614.58 Dollars per Metric Ton
COPPER Global Price of Copper $9474.24 Dollars per Metric Ton
WHEAT Global Price of Wheat $249.18 Dollars per Metric Ton
Year-over-Year Comparison
Compare current prices with the same month last year to identify trends:
def yoy_comparison(code):
"""Compare latest monthly value with same month a year ago."""
data = get_commodity(code, interval="monthly")
meta = data["meta"]
records = data["data"]
if len(records) < 13:
return None
current = records[0]
year_ago = records[12]
change = ((current["value"] - year_ago["value"]) / year_ago["value"]) * 100
return {
"name": meta["name"],
"unit": meta["unit"],
"current_date": current["date"],
"current_value": current["value"],
"year_ago_date": year_ago["date"],
"year_ago_value": year_ago["value"],
"yoy_change_pct": round(change, 1),
}
energy = ["WTI", "BRENT", "NATURAL_GAS", "GASOLINE_US"]
print(f"{'Commodity':<15} {'Current':>10} {'Year Ago':>10} {'YoY Change':>12}")
print("-" * 50)
for code in energy:
result = yoy_comparison(code)
if result:
direction = "+" if result["yoy_change_pct"] > 0 else ""
print(f"{code:<15} ${result['current_value']:>8} "
f"${result['year_ago_value']:>8} "
f"{direction}{result['yoy_change_pct']}%")
Loading into Pandas DataFrame
For deeper analysis, load commodity data into a Pandas DataFrame:
import pandas as pd
def commodity_to_dataframe(code, interval="monthly"):
"""Fetch commodity data and return as a Pandas DataFrame."""
data = get_commodity(code, interval=interval)
df = pd.DataFrame(data["data"])
df["date"] = pd.to_datetime(df["date"])
df = df.set_index("date").sort_index()
df.attrs["name"] = data["meta"]["name"]
df.attrs["unit"] = data["meta"]["unit"]
return df
# Load WTI daily prices
wti = commodity_to_dataframe("WTI", interval="daily")
print(f"{wti.attrs['name']}")
print(f"Date range: {wti.index.min().date()} to {wti.index.max().date()}")
print(f"Records: {len(wti)}")
print(f"\nDescriptive statistics:")
print(wti.describe())
# Calculate 20-day moving average
wti["ma_20"] = wti["value"].rolling(window=20).mean()
print(f"\nLatest value: ${wti['value'].iloc[-1]:.2f}")
print(f"20-day MA: ${wti['ma_20'].iloc[-1]:.2f}")
Correlation Analysis
Compare price movements across commodities to find correlations:
import pandas as pd
codes = ["WTI", "BRENT", "NATURAL_GAS", "COPPER", "ALUMINUM"]
# Fetch all commodities and merge on date
frames = {}
for code in codes:
df = commodity_to_dataframe(code)
frames[code] = df["value"]
combined = pd.DataFrame(frames).dropna()
# Calculate monthly returns
returns = combined.pct_change().dropna()
# Correlation matrix
print("Correlation Matrix (Monthly Returns)")
print("=" * 60)
print(returns.corr().round(2).to_string())
Output:
Correlation Matrix (Monthly Returns)
============================================================
WTI BRENT NATURAL_GAS COPPER ALUMINUM
WTI 1.00 0.97 0.38 0.52 0.45
BRENT 0.97 1.00 0.35 0.50 0.44
NATURAL_GAS 0.38 0.35 1.00 0.21 0.18
COPPER 0.52 0.50 0.21 1.00 0.72
ALUMINUM 0.45 0.44 0.18 0.72 1.00
WTI and Brent are highly correlated (0.97) as expected. Copper and Aluminum also show strong co-movement (0.72), both being industrial metals sensitive to global manufacturing demand.
Data Source and Update Frequency
All commodity data is sourced from the Federal Reserve Economic Data (FRED) maintained by the Federal Reserve Bank of St. Louis. Update frequency depends on the underlying series:
- Daily series (WTI, Brent, Natural Gas, Diesel, Heating Oil, Jet Fuel, Propane) — updated every business day
- Weekly series (Gasoline) — updated every Monday
- Monthly series (Metals, Agricultural, Indices, Coal, Uranium) — updated once per month, typically with a 1-2 month lag
Data goes back to 1986 for major energy commodities (WTI, Brent) and to the 1990s for most metals and agricultural commodities.
API Endpoints Summary
| Endpoint | Description |
|---|---|
| GET /api/commodities/historical/{CODE} | Historical prices for a specific commodity |
| GET /api/commodities/historical/ALL_COMMODITIES | Global commodity price index |
All endpoints require authentication via api_token parameter. The Commodities API is available across all plans, including free plan.