Time Series
Retrieve historical time series data for any commodity.
Get Time Series
GET
/v1/commodities/{slug}/series
Returns historical time series data for a specific commodity and series type. Supports flexible date ranges and frequency options.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | Commodity identifier in the URL path (e.g., "WTI_CRUDE_OIL") |
| type | string | Required | Series type: "price", "volume", "open_interest", "production", "stocks", "yield", "planted_acres", "harvested_acres", "refinery_inputs", "ending_stocks" |
| start_date | string | Optional | Start date (YYYY-MM-DD). Defaults to 1 year ago. |
| end_date | string | Optional | End date (YYYY-MM-DD). Defaults to today. |
| frequency | string | Optional | Data frequency: "daily" (default), "weekly", "monthly" |
| transform | string | Optional | Data transform: "none" (default), "change", "pct_change", "cumulative" |
| limit | integer | Optional | Maximum data points to return (max 10,000). Useful with sort_order=desc to get latest N points. |
| sort_order | string | Optional | Sort order: "asc" (default) or "desc" |
Example Request
curl -X GET "https://commodityfundamentals.com/api/v1/commodities/GOLD/series?type=price&start_date=2024-01-01&frequency=weekly" \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
response = requests.get(
"https://commodityfundamentals.com/api/v1/commodities/GOLD/series",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={
"type": "price",
"start_date": "2024-01-01",
"frequency": "weekly"
}
)
series = response.json()
for point in series["data"]:
print(point["date"], point["value"])
require "net/http"
require "json"
uri = URI("https://commodityfundamentals.com/api/v1/commodities/GOLD/series")
uri.query = URI.encode_www_form(
type: "price",
start_date: "2024-01-01",
frequency: "weekly"
)
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer YOUR_API_KEY"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http|
http.request(req)
}
series = JSON.parse(res.body)
series["data"].each { |v| puts "#{v["date"]}: #{v["value"]}" }
Example Response
{
"data": [
{ "date": "2024-01-05", "value": 2044.50, "open": 2062.98, "high": 2078.40, "low": 2024.10, "close": 2044.50 },
{ "date": "2024-01-12", "value": 2049.70, "open": 2046.80, "high": 2062.30, "low": 2017.30, "close": 2049.70 },
{ "date": "2024-01-19", "value": 2029.30, "open": 2052.10, "high": 2059.60, "low": 2005.40, "close": 2029.30 }
],
"meta": {
"commodity_id": "GOLD",
"type": "price",
"frequency": "weekly",
"unit": "USD/troy oz",
"transform": "none",
"count": 25
}
}
Series Types
The following series types can be passed as the
type parameter.
Use the Get Commodity
endpoint to check which are available for a given commodity.
| Series Type | Description | Frequency |
|---|---|---|
| price | OHLC price data (EIA spot prices, USDA prices received, FRED metals/softs) | Daily/Monthly |
| volume | Trading volume for the front-month contract | Daily |
| open_interest | Total open interest across all contract months | Daily |
| production | Crude oil or grain production (barrels/day or bushels) | Monthly |
| stocks | Petroleum ending stocks or natural gas storage (Bcf) | Weekly/Monthly |
| yield | Grain yield in bushels per acre | Annual |
| planted_acres | Area planted in acres | Annual |
| harvested_acres | Area harvested in acres | Annual |
| refinery_inputs | Crude inputs to refineries (barrels/day) | Monthly |
| ending_stocks | USDA WASDE ending stocks (1000 MT) | Annual |
COT positioning data (Legacy and Disaggregated) is available through the dedicated
CFTC endpoint
rather than the time series endpoint.
Transforms
Apply mathematical transforms to the data before it is returned:
| Transform | Description | Formula |
|---|---|---|
| none | No transformation, raw values | y(t) |
| change | Period-over-period change | y(t) - y(t-1) |
| pct_change | Percentage change | (y(t) - y(t-1)) / y(t-1) * 100 |
| cumulative | Cumulative sum from start | sum(y(0)..y(t)) |