Documentation
CommodityPriceAPI
CommodityPriceAPI provides a simple REST API for live and historical rates for 520+ commodities in a simple JSON format. Rates are available historically for all days going back up to 1st January, 1990.
This documentation provides complete details of the features and options available in this API.
Base API URL
https://api.commoditypriceapi.com/v3Versioning#
The API version is part of the URL path. The current version is v3, which this documentation describes. Earlier version '/v2' remain available at their own path and are not affected by changes to newer versions.
Documentation
Authentication
The CommodityPriceAPI uses API keys to authenticate requests. Each request must contain your API key via an apiKey query parameter or x-api-key request header.
In order to use the API, you need to sign up. No credit card required. Once you've created your account, get your API key from your dashboard, where you can also extend your trial, manage your subscription, and monitor usage.
Get Your API Key#
You can get your API key from the Dashboard page.
Send Your API Key#
The API Key may be sent in two ways:
- Request Parameter — include an
apiKeyparameter in your request's query string. - Request Header — include an
x-api-keyrequest header with each request.
Track Usage#
You can track your API usage in the Dashboard and via the Usage endpoint.
Documentation
Errors and Codes
The CommodityPriceAPI returns error status using both conventional HTTP codes and error messages within the JSON response body. The error body will have the following attributes:
Error Body#
timestampString- ISO 8601 date-time string (e.g. 2026-09-07T10:27:50.362Z) identifying when the error response was generated.
pathString- The request path relative to the base URL, e.g. /rates/latest.
codeInteger- The HTTP status code of the error, repeated in the body (e.g. 400, 404).
errorString- A short, standardized error code indicating the type of error. Common values include VALIDATION_ERROR, UNAUTHORIZED, PAYMENT_REQUIRED, LIMIT_REACHED, SYMBOL_NOT_FOUND, etc. Useful for programmatic error handling.
messageString- A human-readable description providing details about the error. It explains what went wrong and may offer guidance on how to resolve the issue.
unresolvedObject- Optional. Present on 404 SYMBOL_NOT_FOUND responses from the latest, intraday, historical, time-series and fluctuation endpoints. Keyed by each requested symbol; every entry has a message and, when close matches exist, a suggestions array of valid symbols. The same object appears on 206 Partial Content responses, and on 200 responses where a symbol had exactly one possible match and was answered with it (that entry carries resolvedTo instead of suggestions).
{
"timestamp": "2026-09-08T09:00:00.000Z",
"path": "/rates/latest",
"code": 404,
"error": "SYMBOL_NOT_FOUND",
"message": "The symbol is not supported, please visit the documentation for a list of supported symbols",
"unresolved": {
"ZW": {
"message": "Did you mean ZW-SPOT (Wheat Spot) or ZW-FUT (Wheat Futures)?",
"suggestions": [
"ZW-SPOT",
"ZW-FUT"
]
},
"XYZ": {
"message": "We don't recognise this symbol code and could not match it to any commodity we carry. See our symbols page for the symbols this API uses."
}
}
}HTTP Status Codes#
The table below lists the HTTP status codes the API returns. Success responses (200 and 206) carry the endpoint's response object; error responses carry the error body described above. The table covers the codes common to all endpoints; endpoint-specific errors are listed under each endpoint.
Billing: every 2xx response counts against your quota. Error responses (4xx and 5xx) are not billed.
| Code | Error | Message |
|---|---|---|
| 200 | — | Request succeeded. All requested symbols were returned. A symbol matched to a single alternative is reported in the unresolved object with resolvedTo. |
| 206 | — | Request succeeded, but some requested symbols could not be returned. They are listed in the unresolved object of the response. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 401 | UNAUTHORIZED | API key is missing from the request. Please include your API key in the request headers. |
| 402 | PAYMENT_REQUIRED | Please extend your trial or subscribe to a plan to continue using the API |
| 402 | PAYMENT_REQUIRED | User does not have an active subscription. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded |
| 402 | PAYMENT_REQUIRED | The time-series endpoint is not available on your current plan (Basic). Please upgrade your plan to access it. |
| 402 | PAYMENT_REQUIRED | The fluctuation endpoint is not available on your current plan (Basic). Please upgrade your plan to access it. |
| 402 | PAYMENT_REQUIRED | The intraday endpoint is only available on the Advanced and Enterprise plans (your current plan: Standard). Please upgrade your plan to access it. |
| 403 | LIMIT_REACHED | API key usage limit reached, Please upgrade your plan. |
| 403 | LIMIT_REACHED | You have reached the maximum request count for the month. Please upgrade your plan to continue using the API. |
| 404 | USER_NOT_FOUND | The user with the specified API key was not found (Invalid API key). |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 429 | TOO_MANY_REQUESTS | Too many requests, please try again in a minute |
| 500 | SERVER_ERROR | Internal Server Error |
Requests to an unknown path return 404 with a body of the form { status, message, path }.
Documentation
Supported Symbols
Browse the full list of commodity symbols supported by the API, including their category, default currency, and measuring unit.
Documentation
Futures Contracts
Besides the continuous futures symbols such as WTIOIL-FUT, which follow the front month and roll to the next one at expiry, the API lists the individual delivery months of 11 futures: 281 contract months, out to December 2035 for WTI. Each month is an ordinary symbol, such as WTIOIL-FUT-DEC26.
Pass contract symbols to Latest Rates, Historical Rates, Time Series and Fluctuation as you would any other symbol, mixed freely with spot symbols in one request. Each contract counts as one symbol toward your plan's symbols per request.
Use a contract month when you have to match a specific contract: hedges, valuations, delivery pricing, or the shape of the forward curve. Use the continuous symbol for a single long-running chart of the futures price.
$ curl "https://api.commoditypriceapi.com/v3/rates/latest?symbols=WTIOIL-FUT-NOV26,WTIOIL-FUT-DEC26,WTIOIL-FUT-JAN27,WTIOIL-FUT-FEB27,WTIOIL-FUT-MAR27" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/latest?symbols=WTIOIL-FUT-NOV26,WTIOIL-FUT-DEC26,WTIOIL-FUT-JAN27,WTIOIL-FUT-FEB27,WTIOIL-FUT-MAR27",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/latest",
params={"symbols": "WTIOIL-FUT-NOV26,WTIOIL-FUT-DEC26,WTIOIL-FUT-JAN27,WTIOIL-FUT-FEB27,WTIOIL-FUT-MAR27"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/latest?symbols=WTIOIL-FUT-NOV26,WTIOIL-FUT-DEC26,WTIOIL-FUT-JAN27,WTIOIL-FUT-FEB27,WTIOIL-FUT-MAR27");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Symbol Format#
A contract symbol is its continuous symbol, a hyphen, the three-letter delivery month and the two-digit year: WTIOIL-FUT-DEC26 is WTI crude oil for December 2026 delivery, ZW-FUT-MAR27 is wheat for March 2027. Each month uses the same unit and quote currency as its continuous symbol, returned in metadata as usual.
| Commodity | Continuous | Months | Furthest |
|---|---|---|---|
| WTI crude oil | WTIOIL-FUT | 60 | Dec 2035 |
| Natural gas | NG-FUT | 60 | Oct 2031 |
| Brent crude oil | BRENTOIL-FUT | 36 | Nov 2029 |
| Heating oil | HO-FUT | 28 | Dec 2029 |
| RBOB gasoline | RB-FUT | 26 | Dec 2028 |
| Copper | XCU-FUT | 24 | Nov 2028 |
| Soybeans | SOYBEAN-FUT | 17 | Nov 2029 |
| Wheat | ZW-FUT | 14 | Jul 2029 |
| Oats | OAT-FUT | 7 | Sep 2028 |
| Rough rice | RR-FUT | 6 | Sep 2027 |
| Lumber | LB-FUT | 3 | Mar 2027 |
| Total | 281 | ||
/symbols?underlying=… always returns the current set.Listing Contract Months#
The Symbols endpoint takes three filters for futures. underlying=WTIOIL-FUT returns the live months of one continuous symbol. contract=futures returns every futures symbol, continuous and dated, and contract=spot leaves them out. includeExpired=true adds months that have already expired, which are hidden by default.
Contract rows carry four extra fields: contract, deliveryMonth (YYYY-MM), expiresAt, the last trading day (YYYY-MM-DD), and underlying, the continuous symbol. The order of rows is not guaranteed; sort by deliveryMonth before you build a curve.
$ curl "https://api.commoditypriceapi.com/v3/symbols?underlying=WTIOIL-FUT" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/symbols?underlying=WTIOIL-FUT",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/symbols",
params={"underlying": "WTIOIL-FUT"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/symbols?underlying=WTIOIL-FUT");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);{
"success": true,
"symbols": [
{
"symbol": "WTIOIL-FUT-NOV26",
"category": "Energy",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "Bbl",
"name": "Barrel"
},
"name": "Crude Oil WTI Futures Nov 2026",
"description": "November 2026 delivery month of the NYMEX Light Sweet Crude Oil Futures contract (CLX26)",
"status": "active",
"contract": "futures",
"deliveryMonth": "2026-11",
"expiresAt": "2026-10-20",
"underlying": "WTIOIL-FUT"
},
{
"symbol": "WTIOIL-FUT-DEC26",
"category": "Energy",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "Bbl",
"name": "Barrel"
},
"name": "Crude Oil WTI Futures Dec 2026",
"description": "December 2026 delivery month of the NYMEX Light Sweet Crude Oil Futures contract (CLZ26)",
"status": "active",
"contract": "futures",
"deliveryMonth": "2026-12",
"expiresAt": "2026-11-20",
"underlying": "WTIOIL-FUT"
}
]
}Building a Forward Curve#
Take the months from /symbols?underlying=… and request them together from Latest Rates. The rates, in delivery order, are the forward curve: falling prices further out, as below, mean backwardation; rising prices mean contango.
A request can hold as many symbols as your plan allows per request; more returns 402 PAYMENT_REQUIRED. Split a long curve, such as the 60 WTI months, across several requests.
{
"success": true,
"timestamp": 1792058459,
"rates": {
"WTIOIL-FUT-NOV26": 94.71,
"WTIOIL-FUT-DEC26": 93.6,
"WTIOIL-FUT-JAN27": 92.56,
"WTIOIL-FUT-FEB27": 91.26,
"WTIOIL-FUT-MAR27": 89.81
},
"metadata": {
"WTIOIL-FUT-NOV26": {
"unit": "Bbl",
"quote": "USD"
},
"WTIOIL-FUT-DEC26": {
"unit": "Bbl",
"quote": "USD"
},
"WTIOIL-FUT-JAN27": {
"unit": "Bbl",
"quote": "USD"
},
"WTIOIL-FUT-FEB27": {
"unit": "Bbl",
"quote": "USD"
},
"WTIOIL-FUT-MAR27": {
"unit": "Bbl",
"quote": "USD"
}
}
}unresolved; read them from Historical Ratesinstead. Your dashboard's Symbols page lists the update interval of every symbol.Daily History and Settlement#
Historical Rates, Time Series and Fluctuation return one open/high/low/close row per trading day for each contract, and closeis the exchange's daily settlement price. A day's row is written when the exchange publishes its preliminary settlement and updated if the final figure differs.
Contract history begins in October 2026, when contract months were added to the API. For longer history of a futures price, use the continuous symbol.
$ curl "https://api.commoditypriceapi.com/v3/rates/time-series?symbols=WTIOIL-FUT-DEC26&startDate=2026-10-12&endDate=2026-10-14" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/time-series?symbols=WTIOIL-FUT-DEC26&startDate=2026-10-12&endDate=2026-10-14",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/time-series",
params={"symbols": "WTIOIL-FUT-DEC26", "startDate": "2026-10-12", "endDate": "2026-10-14"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/time-series?symbols=WTIOIL-FUT-DEC26&startDate=2026-10-12&endDate=2026-10-14");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);{
"success": true,
"startDate": "2026-10-12",
"endDate": "2026-10-14",
"rates": {
"2026-10-12": {
"WTIOIL-FUT-DEC26": {
"open": 90.98,
"high": 93.43,
"low": 88.9,
"close": 92.86
}
},
"2026-10-13": {
"WTIOIL-FUT-DEC26": {
"open": 92.4,
"high": 94.09,
"low": 90.85,
"close": 93.17
}
},
"2026-10-14": {
"WTIOIL-FUT-DEC26": {
"open": 93.73,
"high": 94.87,
"low": 93.06,
"close": 93.9
}
}
}
}Expiry and New Months#
The day after its expiresAt, a contract's status becomes expired. It leaves the default /symbols list, and Latest Rates stops returning a rate for it: the symbol is listed in unresolved with an expiredOn date, with status 206 when other symbols in the request were returned, or 404 when it was the only one.
Its daily history up to expiry stays available from the historical endpoints, and the symbol is never reused for another contract. New delivery months are added automatically as exchanges list them, so a curve built from /symbols?underlying=… rolls forward on its own.
{
"success": true,
"timestamp": 1792575600,
"rates": {
"WTIOIL-FUT-DEC26": 93.42
},
"metadata": {
"WTIOIL-FUT-DEC26": {
"unit": "Bbl",
"quote": "USD"
}
},
"unresolved": {
"WTIOIL-FUT-NOV26": {
"message": "WTIOIL-FUT-NOV26 is a futures contract that expired on 2026-10-20; it has no current price. Its settlement history (open/high/low/close, close = settlement) is still available from /rates/historical, /rates/time-series and /rates/open-high-low-close; the live months of WTIOIL-FUT are listed by /symbols?underlying=WTIOIL-FUT.",
"expiredOn": "2026-10-20"
}
}
}Documentation
Quoted Currencies
Standard, Advanced and Enterprise subscribers can request rates in any of the supported quote currencies. Browse the full list to find the currency code you need.
Endpoints
Usage Endpoint
/v3/usageReturns the current usage and quota information for your account.
$ curl https://api.commoditypriceapi.com/v3/usage \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/usage",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/usage",
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/usage");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader.
Response Object#
planstring- Your current plan name in lowercase (e.g.
basic,standard,advanced). quotainteger- Your current allotted quota.
usedinteger- Your usage since start of month, subscription, or trial.
{
"plan": "basic",
"quota": 8000,
"used": 0
}Endpoints
Symbols Endpoint
/v3/symbolsReturns the complete information of all supported commodities, including symbol, name, category, default quote currency (code, name, symbol), measuring unit, status and update interval. Deprecated symbols are included with status: "inactive" and a deprecationDate.
Futures contract months are included and carry four extra fields. Filter the list with underlying, contract and includeExpired; see Futures Contracts.
$ curl https://api.commoditypriceapi.com/v3/symbols \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/symbols",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/symbols",
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/symbols");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. underlyingstringoptional- Only the contract months of this continuous futures symbol, e.g.
WTIOIL-FUT. Case-insensitive. contractstringoptionalfuturesfor futures symbols only, continuous and dated;spotto leave them out. Any other value returns 400 VALIDATION_ERROR.includeExpiredbooleanoptional- Also list contract months that have expired. Defaults to
false.
Response Object#
successbooleantrueif the request was successful,falseif there was an error.symbolsobject []- Array of available commodity symbols with their metadata.
symbols.symbolstring- The symbol code to use in the
symbolsquery parameter of the rate endpoints. symbols.namestring- Human-readable commodity name.
symbols.descriptionstring- Short description of the commodity. May be empty for some symbols.
symbols.categorystring- Commodity category, e.g.
Metals,Energy,Agriculture,Industrial. symbols.currencyobject- Default quote currency:
code,nameandsymbol. symbols.unitobject- Measuring unit:
symbolandname. symbols.statusstringactive,inactive(deprecated; latest rates unavailable) orexpired(a futures contract past its last trading day; listed only withincludeExpired=true).symbols.updateIntervalstring- How often the rate updates. One of
PER_SECOND,PER_MINUTE,PER_10_MINUTES,PER_HOUR,PER_DAY,PER_WEEK,PER_MONTH,PER_6_MONTHS. symbols.exchangestring- Optional. Data source for the symbol, e.g.
World Bank. Present only for some symbols. symbols.deprecationDatestring- Optional. Present only for inactive symbols. Format:
YYYY-MM-DD. symbols.contractstring- Futures contract months only. Always
futures. symbols.deliveryMonthstring- Futures contract months only. The delivery month. Format:
YYYY-MM. symbols.expiresAtstring- Futures contract months only. The last trading day. Format:
YYYY-MM-DD. symbols.underlyingstring- Futures contract months only. The continuous futures symbol the month belongs to, e.g.
WTIOIL-FUT.
{
"success": true,
"symbols": [
{
"symbol": "XAU",
"category": "Metals",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "T.oz",
"name": "Troy Ounce"
},
"name": "Gold",
"description": "Gold spot price per troy ounce",
"status": "active",
"updateInterval": "PER_SECOND"
},
{
"symbol": "WTIOIL-FUT",
"category": "Energy",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "Bbl",
"name": "Barrel"
},
"name": "Crude Oil WTI Futures",
"status": "active",
"updateInterval": "PER_MINUTE"
},
{
"symbol": "WTIOIL-FUT-DEC26",
"category": "Energy",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "Bbl",
"name": "Barrel"
},
"name": "Crude Oil WTI Futures Dec 2026",
"description": "December 2026 delivery month of the NYMEX Light Sweet Crude Oil Futures contract (CLZ26)",
"status": "active",
"updateInterval": "PER_MINUTE",
"contract": "futures",
"deliveryMonth": "2026-12",
"expiresAt": "2026-11-20",
"underlying": "WTIOIL-FUT"
},
{
"symbol": "XCU-SPOT",
"category": "Metals",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "lb",
"name": "Pound"
},
"name": "Copper Spot",
"status": "active",
"updateInterval": "PER_MINUTE"
},
{
"symbol": "NG-EU",
"category": "Energy",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "MMBtu",
"name": "Million British Thermal Units"
},
"name": "Natural Gas, Europe",
"status": "active",
"updateInterval": "PER_MONTH",
"exchange": "World Bank"
},
{
"symbol": "UANEU",
"category": "Industrial",
"currency": {
"code": "USD",
"name": "US Dollar",
"symbol": "$"
},
"unit": {
"symbol": "T",
"name": "Metric Ton"
},
"name": "Urea Ammonium Nitrate",
"status": "inactive",
"updateInterval": "PER_MINUTE",
"deprecationDate": "2024-04-14"
}
]
}Endpoints
Latest Rates
/v3/rates/latestReturns the latest rates for the specified symbols. Depending on your subscription plan, the latest rates may be delayed by up to 10 minutes.
Basic and legacy Lite users receive rates in the default quote currency of a commodity. Standard, Advanced and Enterprise users can customize the quote currency via a query parameter.
Symbol codes we don't recognise, or symbols that have no current rate, are reported in unresolved with a 206 Partial Content status.
If an unrecognised symbol code has exactly one possible match — PL can only mean XPT (Platinum) — the API returns that symbol's rate and records the substitution in unresolved with a resolvedTo field. Nothing was dropped, so the status stays 200. Ambiguous symbols, with several possible matches, are never guessed.
Latest rates for deprecated symbols are not available; however, you can access historical rates up to a symbol's deprecation date. View deprecated symbols.
$ curl "https://api.commoditypriceapi.com/v3/rates/latest?symbols=xau,wtioil-fut,zw,pl" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/latest?symbols=xau,wtioil-fut,zw,pl",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/latest",
params={"symbols": "xau,wtioil-fut,zw,pl"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/latest?symbols=xau,wtioil-fut,zw,pl");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolsstring []required- Comma-separated list of commodity symbols. Case-insensitive; surrounding whitespace and duplicates are ignored.
quotestringoptional- Target currency for the exchange rate; if omitted (or set to
default), the default quote currency of each commodity is used. Ignored on the Basic plan and the legacy Lite plan. View supported quote currencies. metadatabooleanoptional- Whether to include the
metadataobject (unit and quote currency per symbol) in the response. Defaults totrue. Passfalseto receive only the rates and reduce the payload size. Any other value is treated as the default.
Response Object#
successboolean- Boolean indicator of API request success.
truefor successful requests. timestampnumber- Unix timestamp indicating when the response was generated.
ratesobject- Object containing the current rates for each requested commodity, keyed by symbol.
metadataobject- Object containing metadata for the symbols, such as their unit and quote currency. Omitted when the request sets
metadata=false. unresolvedobject- Present when a requested symbol was not returned as asked (206, 404 SYMBOL_NOT_FOUND) or was matched to a single alternative (200). Keyed by the symbol you sent. Each entry has a
messageplus either asuggestionsarray (several possible matches, no rate returned) orresolvedTo(one possible match — its rate is inratesunder that symbol). An expired futures contract has anexpiredOndate instead. warningstring- Only present when currency conversion for the requested
quoteis temporarily unavailable; rates are then returned in their default currencies.
{
"success": true,
"timestamp": 1703866777,
"rates": {
"WTIOIL-FUT": 72.29,
"XAU": 2066.98,
"XPT": 1012.4
},
"metadata": {
"XAU": {
"unit": "T.oz",
"quote": "USD"
},
"WTIOIL-FUT": {
"unit": "Bbl",
"quote": "USD"
},
"XPT": {
"unit": "T.oz",
"quote": "USD"
}
},
"unresolved": {
"PL": {
"message": "PL is not a symbol code used by this API. Platinum is available as \"XPT\", so its rate was returned under that symbol.",
"resolvedTo": "XPT"
},
"ZW": {
"message": "Did you mean ZW-SPOT (Wheat Spot) or ZW-FUT (Wheat Futures)?",
"suggestions": [
"ZW-SPOT",
"ZW-FUT"
]
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | All requested symbols were returned. A symbol matched to a single alternative is reported in unresolved with resolvedTo. |
| 206 | — | Some requested symbols could not be returned and are listed in unresolved. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 404 | QUOTE_NOT_FOUND | The quote currency is invalid, please visit the documentation for a list of valid quote currencies |
Endpoints
Latest Rate by Symbol
/v3/rates/latest/{symbol}Returns the latest rate for one of the ten commodities we poll every second, with bid and ask alongside the rate. Every other symbol is served by Latest Rates.
On every current plan the rate is refreshed every second. Standard, Advanced and Enterprise can quote it in any supported currency; Basic returns USD. On the legacy Lite plan rates are in USD and may be up to 10 minutes old.
$ curl "https://api.commoditypriceapi.com/v3/rates/latest/XPT?include=gram" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/latest/XPT?include=gram",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/latest/XPT",
params={"include": "gram"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/latest/XPT?include=gram");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Supported Symbols#
| Symbols | Details |
|---|---|
| XAU | Gold API |
| XAG | Silver API |
| WTIOIL-SPOT, WTIOIL-FUT, BRENTOIL-SPOT, BRENTOIL-FUT | Oil Price API |
| XCU-SPOT, XCU-FUT | Copper Price API |
| XPT | Platinum Price API |
| XPD | Palladium Price API |
Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolstring (path)required- One of the symbols above, e.g.
/rates/latest/WTIOIL-FUT. Case-insensitive. quotestringoptional- Target currency for the rate; if omitted (or
default), the symbol's native currency (USD) is used. Ignored entirely on the Basic plan and the legacy Lite plan: it is not validated and the rate stays in USD. View supported quote currencies. includestringoptional- Troy-ounce metals only.
gramortolaforXAG,XPTandXPD;gram,tolaorcaratforXAU. Copper and oil take noinclude. metadatabooleanoptional- Whether to include the
metadataobject. Defaults totrue.
Response Object#
rates.{symbol}.ratenumber- Latest price in the symbol's unit (per troy ounce, pound or barrel).
rates.{symbol}.bid / asknumber- Best bid and ask at the same moment.
rates.{symbol}.gramnumber- Price per gram (
rate÷ 31.1035). Present only withinclude=gram. rates.{symbol}.tolanumber- Price per tola (
rate÷ 2.66667). Present only withinclude=tola. rates.XAU.caratsobject- Gold only, present with
include=carat. The per-gram price of each purity, keyed24k_per_gram,22k_per_gram,21k_per_gram,20k_per_gram,18k_per_gram,16k_per_gram,14k_per_gram,12k_per_gram,10k_per_gram,9k_per_gramand8k_per_gram. Each is the 24k per-gram price × carat ÷ 24. metadata.{symbol}objectunitandquotecurrency of the rate. Omitted when the request setsmetadata=false.unresolvedobject- Error responses only. Present on a 404 SYMBOL_NOT_FOUND for an unknown symbol close to one this endpoint serves, and on a 400 for an unknown symbol when the wider catalogue has a match. Keyed by the symbol you sent, each entry has a
messageand asuggestionsarray.
gram, tola and carats are derived from rate only; bid and ask stay per troy ounce. When quote is applied, they are already in that currency.-SPOT symbols are continuous cash prices; -FUT symbols follow the front-month exchange contract on a continuous basis. Neither is an exchange settlement or official benchmark price.{
"success": true,
"timestamp": 1792040400,
"rates": {
"XPT": {
"rate": 1664.1,
"bid": 1663.4,
"ask": 1664.8,
"gram": 53.502
}
},
"metadata": {
"XPT": {
"unit": "T.oz",
"quote": "USD"
}
}
}{
"success": true,
"timestamp": 1792040400,
"rates": {
"XAU": {
"rate": 4441.27,
"bid": 4440.9,
"ask": 4441.64,
"carats": {
"24k_per_gram": 142.79,
"22k_per_gram": 130.8909,
"21k_per_gram": 124.9413,
"20k_per_gram": 118.9917,
"18k_per_gram": 107.0925,
"16k_per_gram": 95.1934,
"14k_per_gram": 83.2942,
"12k_per_gram": 71.395,
"10k_per_gram": 59.4958,
"9k_per_gram": 53.5463,
"8k_per_gram": 47.5967
}
}
},
"metadata": {
"XAU": {
"unit": "T.oz",
"quote": "USD"
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | The rate was returned. |
| 400 | VALIDATION_ERROR | The symbol is in the catalogue but not served by this endpoint (ZW-SPOT). Use /rates/latest. |
| 400 | VALIDATION_ERROR | Unknown symbol that is not close to any symbol this endpoint serves. Use /rates/latest; catalogue-wide suggestions, if any, are in unresolved. |
| 400 | VALIDATION_ERROR | The include value is not valid for the symbol. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded. Returned when the plan allows no symbols per request, e.g. without an active subscription. |
| 404 | SYMBOL_NOT_FOUND | Unknown symbol close to one this endpoint serves (WTIOIL → WTIOIL-SPOT, WTIOIL-FUT). The suggestions are in unresolved. |
| 404 | SYMBOL_NOT_FOUND | The symbol is served by this endpoint but no rate was available for it. |
| 404 | QUOTE_NOT_FOUND | The quote currency is invalid, please visit the documentation for a list of valid quote currencies |
{
"timestamp": "2026-10-16T09:00:00.000Z",
"path": "/rates/latest/WTIOIL",
"code": 404,
"error": "SYMBOL_NOT_FOUND",
"message": "Did you mean WTIOIL-SPOT (Crude Oil WTI Spot) or WTIOIL-FUT (Crude Oil WTI Futures)?",
"unresolved": {
"WTIOIL": {
"message": "Did you mean WTIOIL-SPOT (Crude Oil WTI Spot) or WTIOIL-FUT (Crude Oil WTI Futures)?",
"suggestions": [
"WTIOIL-SPOT",
"WTIOIL-FUT"
]
}
}
}Endpoints
Intraday Rates
/v3/rates/intradayReturns the rates of one commodity through a single UTC day, at an interval of your choice from one minute to one day. Each point is the rate we recorded at that exact mark — 14:05 is the rate observed at 14:05 UTC — not an OHLC bar.
A response holds at most 100 points. Use startTime to move the window through the day, and nextStartTime in the response to know where the next page begins. Each request counts as one call, however many points it returns.
Available on the Advanced and Enterprise plans. On any other plan the endpoint returns 402 PAYMENT_REQUIRED and the call is not counted.
Intraday rates exist for symbols updated every second, every minute or every 10 minutes. Symbols published hourly, daily or less often return 400 BAD_REQUEST. Your dashboard's Symbols page lists the update interval of every symbol.
$ curl "https://api.commoditypriceapi.com/v3/rates/intraday?symbols=XAU&interval=1h&date=2026-10-14&startTime=18:00" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/intraday?symbols=XAU&interval=1h&date=2026-10-14&startTime=18:00",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/intraday",
params={"symbols": "XAU", "interval": "1h", "date": "2026-10-14", "startTime": "18:00"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/intraday?symbols=XAU&interval=1h&date=2026-10-14&startTime=18:00");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolsstringrequired- Exactly one commodity symbol. Case-insensitive. Sending two or more returns 400.
intervalstringrequired- Spacing between points. One of
1m,5m,10m,15m,30m,45m,1h,2h,4h,8h,12h,1d. Case-insensitive. Symbols updated every 10 minutes accept only the multiples of 10 minutes:10m,30m,1h,2h,4h,8h,12h,1d. datestringrequired- The UTC day to read. Format:
YYYY-MM-DD. Cannot be in the future; for today, points stop at the current UTC minute. startTimestringoptional- First mark of the window, as a 24-hour UTC time in
HH:mm. Defaults to00:00. Must fall on a mark of the interval —14:30works for5mor30m, but not for1h. For1dit can only be00:00. metadatabooleanoptional- Whether to include the
metadataobject. Defaults totrue.
metadata; this endpoint takes no quote parameter.Paging Through a Day#
A full day is 1,440 one-minute points or 288 five-minute points, more than one response holds. The window starts at startTime and ends after 100 points, at the end of the day or, for today, at the current minute — whichever comes first.
interval=1m from 00:00 returns 00:00–01:39 with nextStartTime: "01:40". Send that value as startTime to get the next 100 points, and repeat until nextStartTime is null. From 15m upward a whole day fits in one response.
If no rate was recorded at a mark, that point is left out rather than filled in, so count can be lower than the window size.
Response Object#
successboolean- Boolean indicator of API request success.
symbolstring- The symbol the rates belong to.
datestring- The UTC day requested. Format:
YYYY-MM-DD. intervalstring- The interval used, in canonical form (
5Mcomes back as5m). startTimestring- First mark of the window,
HH:mmUTC. countnumber- Number of points in
rates(at most 100). nextStartTimestring | nullHH:mmto pass asstartTimefor the next page, ornullwhen the window reached the end of the day (or the current minute, for today).ratesobject- Rates keyed by ISO 8601 UTC timestamp, e.g.
2026-10-14T18:00:00Z, in ascending order. Values are rounded to two decimals. metadata.{symbol}objectunitandquotecurrency of the rates. Omitted when the request setsmetadata=false.unresolvedobject- Present when the symbol you sent was matched to a single alternative (200, with
resolvedTo—GOLDis answered asXAU) or not recognised at all (404 SYMBOL_NOT_FOUND, withsuggestionswhen close matches exist).
{
"success": true,
"symbol": "XAU",
"date": "2026-10-14",
"interval": "1h",
"startTime": "18:00",
"count": 6,
"nextStartTime": null,
"rates": {
"2026-10-14T18:00:00Z": 3961.27,
"2026-10-14T19:00:00Z": 3958.84,
"2026-10-14T20:00:00Z": 3963.1,
"2026-10-14T21:00:00Z": 3966.45,
"2026-10-14T22:00:00Z": 3964.92,
"2026-10-14T23:00:00Z": 3967.38
},
"metadata": {
"XAU": {
"unit": "T.oz",
"quote": "USD"
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | The intraday rates were returned. |
| 402 | PAYMENT_REQUIRED | The intraday endpoint is only available on the Advanced and Enterprise plans (your current plan: Standard). Please upgrade your plan to access it. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 400 | VALIDATION_ERROR | The 'interval' parameter is required in the query (one of 1m, 5m, 10m, 15m, 30m, 45m, 1h, 2h, 4h, 8h, 12h, 1d). |
| 400 | VALIDATION_ERROR | Date is required in query params. |
| 400 | VALIDATION_ERROR | intraday accepts exactly one symbol in the symbols parameter |
| 400 | VALIDATION_ERROR | Invalid interval '{interval}' for {symbol}: valid intervals for {symbol} are … |
| 400 | VALIDATION_ERROR | Invalid date format: expected YYYY-MM-DD |
| 400 | VALIDATION_ERROR | Invalid Date: The provided date does not exist. |
| 400 | VALIDATION_ERROR | Invalid date: intraday rates are not available for future dates |
| 400 | VALIDATION_ERROR | Invalid startTime: expected a 24-hour time in HH:mm (UTC), e.g. 14:30 |
| 400 | VALIDATION_ERROR | Invalid startTime '{startTime}': it must fall on a {interval} mark (minutes since 00:00 divisible by {minutes}) |
| 400 | BAD_REQUEST | Intraday rates are not available for {symbol}: they exist only for symbols updated every second, minute or 10 minutes |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 404 | DATA_NOT_FOUND | No intraday data found for the specified window |
Endpoints
Historical Rates
/v3/rates/historicalHistorical rates are available for most commodities since 1990-01-01. Query the API for historical rates by passing a date (format YYYY-MM-DD) as a URL parameter.
If the rate of a commodity for a specific date is unavailable, the API falls back to the last available rate before that date and returns it along with its corresponding date. For example, a request for today's date on a commodity whose latest historical rate is two days old returns that two-day-old rate and its date.
For monthly commodities, only their closing rates are available in the historical data. See the available symbols.
Symbol codes we don't recognise, or symbols that have no rate on the requested date and no earlier rate to fall back to, are reported in unresolved with a 206 Partial Content status. If all symbols are supported but none has data for the date, the API returns 404 RATE_NOT_FOUND.
If an unrecognised symbol code has exactly one possible match — PL can only mean XPT (Platinum) — the API returns that symbol's rate and records the substitution in unresolved with a resolvedTo field. Nothing was dropped, so the status stays 200. Ambiguous symbols, with several possible matches, are never guessed.
$ curl "https://api.commoditypriceapi.com/v3/rates/historical?symbols=xau,wtioil-fut,zw,pl&date=2019-01-04" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/historical?symbols=xau,wtioil-fut,zw,pl&date=2019-01-04",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/historical",
params={"symbols": "xau,wtioil-fut,zw,pl", "date": "2019-01-04"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/historical?symbols=xau,wtioil-fut,zw,pl&date=2019-01-04");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolsstring []required- Comma-separated list of commodity symbols. Case-insensitive; duplicates are ignored.
datestringrequired- Date for which the rates are requested. Format:
YYYY-MM-DD.
Response Object#
successboolean- Boolean indicator of API request success.
datestring- Date for which the user requested the commodity price. Format:
YYYY-MM-DD. ratesobject- Object containing the requested rates, keyed by symbol.
rates.datestring- Date for which commodity prices were fetched. May differ from the requested date when the API falls back to the most recent available rate. Format:
YYYY-MM-DD. rates.opennumber- The opening price of the commodity on the given date.
rates.highnumber- The highest price of the commodity recorded on the given date.
rates.lownumber- The lowest price of the commodity recorded on the given date.
rates.closenumber- The closing price of the commodity on the given date.
unresolvedobject- Present when a requested symbol was not returned as asked (206, 404 SYMBOL_NOT_FOUND) or was matched to a single alternative (200). Keyed by the symbol you sent. Each entry has a
messageplus either asuggestionsarray (several possible matches, no rate returned) orresolvedTo(one possible match — its rate is inratesunder that symbol). An expired futures contract has anexpiredOndate instead.
{
"success": true,
"date": "2019-01-04",
"rates": {
"XAU": {
"date": "2019-01-04",
"open": 1295.17,
"high": 1298.49,
"low": 1276.6,
"close": 1284.81
},
"WTIOIL-FUT": {
"date": "2019-01-04",
"open": 46.9,
"high": 49.22,
"low": 46.65,
"close": 47.96
},
"XPT": {
"date": "2019-01-04",
"open": 793.5,
"high": 802.1,
"low": 789.2,
"close": 798.4
}
},
"unresolved": {
"PL": {
"message": "PL is not a symbol code used by this API. Platinum is available as \"XPT\", so its rate was returned under that symbol.",
"resolvedTo": "XPT"
},
"ZW": {
"message": "Did you mean ZW-SPOT (Wheat Spot) or ZW-FUT (Wheat Futures)?",
"suggestions": [
"ZW-SPOT",
"ZW-FUT"
]
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | All requested symbols were returned. |
| 206 | — | Some requested symbols could not be returned and are listed in unresolved. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 400 | VALIDATION_ERROR | Date is required in query params. |
| 400 | VALIDATION_ERROR | Invalid Date Format (YYYY-MM-DD). |
| 400 | VALIDATION_ERROR | Invalid Date: The provided date does not exist. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 404 | RATE_NOT_FOUND | no rates found for the specified date |
Endpoints
Time Series
/v3/rates/time-seriesQuery the API for daily historical rates between two dates of your choice. The difference between start and end date should not exceed 1 year (365 days). Only dates for which data exists are returned; a symbol is omitted from a date it has no rate for.
Available on the Standard, Advanced and Enterprise plans. On Basic the endpoint returns 402 PAYMENT_REQUIRED and the call is not counted.
For monthly commodities, only their closing rates are available in the time-series data.
Symbol codes we don't recognise, or symbols that have no data on any date in the range, are reported in unresolved with a 206 Partial Content status. A symbol counts as resolved if it appears on at least one date; missing days for a resolved symbol are not reported. If all symbols are supported but none has data in the range, the API returns 404 DATA_NOT_FOUND.
If an unrecognised symbol code has exactly one possible match — PL can only mean XPT (Platinum) — the API returns that symbol's rate and records the substitution in unresolved with a resolvedTo field. Nothing was dropped, so the status stays 200. Ambiguous symbols, with several possible matches, are never guessed.
$ curl "https://api.commoditypriceapi.com/v3/rates/time-series?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/time-series?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/time-series",
params={"symbols": "xau,wtioil-fut,zw,pl", "startDate": "2023-12-08", "endDate": "2023-12-13"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/time-series?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolsstring []required- Comma-separated list of commodity symbols. Case-insensitive; duplicates are ignored.
startDatestringrequired- Start date for the time series. Format:
YYYY-MM-DD. endDatestringrequired- End date for the time series. Format:
YYYY-MM-DD. Must not be beforestartDate.
Response Object#
successboolean- Boolean indicator of API request success.
startDatestring- Start date for the time series. Format:
YYYY-MM-DD. endDatestring- End date for the time series. Format:
YYYY-MM-DD. ratesobject- Object containing the requested rates, keyed by date (
YYYY-MM-DD), then by symbol. rates.opennumber- The opening price of the commodity on the given date.
rates.highnumber- The highest price of the commodity recorded on the given date.
rates.lownumber- The lowest price of the commodity recorded on the given date.
rates.closenumber- The closing price of the commodity on the given date.
unresolvedobject- Present when a requested symbol appears on no date in
rates(206, 404 SYMBOL_NOT_FOUND) or was matched to a single alternative (200). Keyed by the symbol you sent. Each entry has amessageplus either asuggestionsarray (several possible matches, no rate returned) orresolvedTo(one possible match — its rate is inratesunder that symbol).
{
"success": true,
"startDate": "2023-12-08",
"endDate": "2023-12-13",
"rates": {
"2023-12-08": {
"XAU": {
"open": 2027.93,
"high": 2033.89,
"low": 1994.49,
"close": 2004.35
},
"WTIOIL-FUT": {
"open": 69.34,
"high": 71.63,
"low": 69.5,
"close": 71.23
},
"XPT": {
"open": 925.1,
"high": 931.4,
"low": 918.7,
"close": 928.2
}
},
"2023-12-12": {
"XAU": {
"open": 1982.79,
"high": 1996.48,
"low": 1977.09,
"close": 1982.44
},
"WTIOIL-FUT": {
"open": 69.91,
"high": 70.17,
"low": 69.67,
"close": 69.83
},
"XPT": {
"open": 921.6,
"high": 927.3,
"low": 915.4,
"close": 919.8
}
},
"2023-12-13": {
"XAU": {
"open": 1982.44,
"high": 2033.06,
"low": 1972.91,
"close": 2032.68
},
"WTIOIL-FUT": {
"open": 71.45,
"high": 72.17,
"low": 71.54,
"close": 72.03
},
"XPT": {
"open": 919.8,
"high": 940.2,
"low": 917.1,
"close": 938.5
}
}
},
"unresolved": {
"PL": {
"message": "PL is not a symbol code used by this API. Platinum is available as \"XPT\", so its rate was returned under that symbol.",
"resolvedTo": "XPT"
},
"ZW": {
"message": "Did you mean ZW-SPOT (Wheat Spot) or ZW-FUT (Wheat Futures)?",
"suggestions": [
"ZW-SPOT",
"ZW-FUT"
]
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | All requested symbols were returned. |
| 206 | — | Some requested symbols could not be returned and are listed in unresolved. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 400 | VALIDATION_ERROR | The 'startDate' parameter is required in the query and must be a string. |
| 400 | VALIDATION_ERROR | The 'endDate' parameter is required in the query and must be a string. |
| 400 | VALIDATION_ERROR | Invalid date format specified for start or end date |
| 400 | VALIDATION_ERROR | Invalid Date: The provided start date or end date does not exist. |
| 400 | VALIDATION_ERROR | start date cannot be after end date |
| 400 | VALIDATION_ERROR | Date range exceeds the allowed limit. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 402 | PAYMENT_REQUIRED | The time-series endpoint is not available on your current plan (Basic). Please upgrade your plan to access it. |
| 404 | DATA_NOT_FOUND | No data found for the specified date range |
Endpoints
Fluctuation
/v3/rates/fluctuationReturns information about how rates of different commodities fluctuate over a date range. Provide a startDate and endDate as query parameters and select which symbols you want to query. Unlike the time-series endpoint, there is no limit on the date range.
Available on the Standard, Advanced and Enterprise plans. On Basic the endpoint returns 402 PAYMENT_REQUIRED and the call is not counted.
For monthly commodities, the fluctuation is computed between the first day of the start month and the first day of the end month. All numeric values are rounded to 2 decimal places.
Symbol codes we don't recognise, or symbols that have no rate in the requested range, are reported in unresolved with a 206 Partial Content status. If all symbols are supported but none has data in the range, the API returns 404 DATA_NOT_FOUND.
If an unrecognised symbol code has exactly one possible match — PL can only mean XPT (Platinum) — the API returns that symbol's rate and records the substitution in unresolved with a resolvedTo field. Nothing was dropped, so the status stays 200. Ambiguous symbols, with several possible matches, are never guessed.
$ curl "https://api.commoditypriceapi.com/v3/rates/fluctuation?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13" \
-H "x-api-key: YOUR_API_KEY"const res = await fetch(
"https://api.commoditypriceapi.com/v3/rates/fluctuation?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13",
{ headers: { "x-api-key": "YOUR_API_KEY" } },
);
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://api.commoditypriceapi.com/v3/rates/fluctuation",
params={"symbols": "xau,wtioil-fut,zw,pl", "startDate": "2023-12-08", "endDate": "2023-12-13"},
headers={"x-api-key": "YOUR_API_KEY"},
)
print(res.json())<?php
$ch = curl_init("https://api.commoditypriceapi.com/v3/rates/fluctuation?symbols=xau,wtioil-fut,zw,pl&startDate=2023-12-08&endDate=2023-12-13");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["x-api-key: YOUR_API_KEY"],
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);Request Object#
apiKeystringrequired- Your unique API key. Note: may also be passed via
x-api-keyheader. symbolsstring []required- Comma-separated list of commodity symbols. Case-insensitive; duplicates are ignored.
startDatestringrequired- Start date for the fluctuation. Format:
YYYY-MM-DD. endDatestringrequired- End date for the fluctuation. Format:
YYYY-MM-DD.
Response Object#
successboolean- Boolean indicator of API request success.
startDatestring- Start date for the fluctuation. Format:
YYYY-MM-DD. endDatestring- End date for the fluctuation. Format:
YYYY-MM-DD. ratesobject- Object containing the requested rates per symbol.
rates.startRatenumber- Starting rate for the fluctuation.
rates.endRatenumber- Ending rate for the fluctuation.
rates.changenumber- The change between the starting and ending rates. Negative values represent a decrease.
rates.changePercentnumber- The change percent between the starting and ending rates. Negative values represent a decrease.
unresolvedobject- Present when a requested symbol was not returned as asked (206, 404 SYMBOL_NOT_FOUND) or was matched to a single alternative (200). Keyed by the symbol you sent. Each entry has a
messageplus either asuggestionsarray (several possible matches, no rate returned) orresolvedTo(one possible match — its rate is inratesunder that symbol). An expired futures contract has anexpiredOndate instead.
{
"success": true,
"startDate": "2023-12-08",
"endDate": "2023-12-13",
"rates": {
"WTIOIL-FUT": {
"startRate": 71.23,
"endRate": 69.83,
"change": -1.4,
"changePercent": -1.97
},
"XAU": {
"startRate": 2004.35,
"endRate": 2032.68,
"change": 28.33,
"changePercent": 1.41
},
"XPT": {
"startRate": 928.2,
"endRate": 938.5,
"change": 10.3,
"changePercent": 1.11
}
},
"unresolved": {
"PL": {
"message": "PL is not a symbol code used by this API. Platinum is available as \"XPT\", so its rate was returned under that symbol.",
"resolvedTo": "XPT"
},
"ZW": {
"message": "Did you mean ZW-SPOT (Wheat Spot) or ZW-FUT (Wheat Futures)?",
"suggestions": [
"ZW-SPOT",
"ZW-FUT"
]
}
}
}HTTP Status Codes#
| Code | Error | Message |
|---|---|---|
| 200 | — | All requested symbols were returned. |
| 206 | — | Some requested symbols could not be returned and are listed in unresolved. |
| 400 | VALIDATION_ERROR | symbols parameter is required in the query parameters. |
| 400 | VALIDATION_ERROR | The 'startDate' parameter is required in the query and must be a string. |
| 400 | VALIDATION_ERROR | The 'endDate' parameter is required in the query and must be a string. |
| 400 | VALIDATION_ERROR | Invalid Date Format (YYYY-MM-DD). |
| 400 | VALIDATION_ERROR | Start date cannot be after end date |
| 400 | VALIDATION_ERROR | Invalid Date: The provided start date or end date does not exist. |
| 402 | PAYMENT_REQUIRED | Maximum symbols per request exceeded |
| 404 | SYMBOL_NOT_FOUND | The symbol is not supported, please visit the documentation for a list of supported symbols |
| 402 | PAYMENT_REQUIRED | The fluctuation endpoint is not available on your current plan (Basic). Please upgrade your plan to access it. |
| 404 | DATA_NOT_FOUND | No data found for the given date range |