> TickerLayer documentation for AI agents and LLMs, the Markdown version of https://tickerlayer.com/docs/products/commodities
> REST base URL https://api.tickerlayer.com, API key in the `x-api-key` header. WebSocket wss://stream.tickerlayer.com?apiKey=YOUR_API_KEY.
> Any docs page reads as Markdown at its URL plus `.md`. Index: https://tickerlayer.com/llms.txt · Full API reference: https://tickerlayer.com/llms-full.txt

# Commodities

Indicative reference prices for precious and industrial metals, energy benchmarks, and agricultural contracts, normalized for dashboards, research tooling, and cross-asset displays. Not a claim about physical delivery, warehouse stocks, or venue-listed futures.

- **Auth:** x-api-key header
- **Base path:** /commodities
- **WebSocket:** commodities.quotes · commodities.trades
- **Symbol format:** Canonical codes and aliases (e.g. XAUUSD, WTIUSD)

Data is consolidated and indicative: it may differ materially from any single venue or official settlement print.

## Symbols

Metals

Precious and industrial metals vs USD.

XAUUSD XAGUSD XPTUSD XPDUSD COPPERUSD

Energy

Oil and gas benchmarks.

WTIUSD BRENTUSD NGASUSD

Agriculture

Grains and softs. SUGARUSD values are cents per pound.

WHEATUSD CORNUSD SOYBEANUSD SUGARUSD

Use `GET /commodities/symbols` to list the canonical commodity symbols.

Accepted aliases map to canonical codes, for example `USOILUSD` and `CL1` to `WTIUSD`; `XBRUSD` and `BZUSD` to `BRENTUSD`; `HG1` to `COPPERUSD`. The symbol list returns canonical codes; quote and aggregate routes accept aliases where configured, and responses carry the canonical code (a request for `CL1` answers as `WTIUSD`).

## Symbol list

**Endpoint:** `GET /commodities/symbols`

Canonical commodity symbols for the REST API. Aliases are accepted on quote/snapshot/aggregate routes but are not repeated in this list.

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/symbols" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/symbols",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/commodities/symbols", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/commodities/symbols", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbols": [
    { "symbol": "BRENTUSD", "name": "Brent crude oil" },
    { "symbol": "CANOLAUSD", "name": "Canola / rapeseed" },
    { "symbol": "XAUUSD", "name": "Gold" },
    { "symbol": "WTIUSD", "name": "WTI crude oil" }
  ]
}
```

## Latest quote

**Endpoint:** `GET /commodities/quote/:symbol`

Consolidated bid/ask with sizes and timestamp from the aggregated commodity quote view.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | Yes | Enabled commodity symbol (e.g. XAUUSD, WTIUSD). Trimmed and uppercased before lookup. Discover tickers with GET /commodities/symbols. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/quote/XAUUSD" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/quote/XAUUSD",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/commodities/quote/XAUUSD", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/commodities/quote/XAUUSD", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbol": "XAUUSD",
  "bid": 2318.10,
  "ask": 2318.74,
  "bid_size": 72,
  "ask_size": 68,
  "timestamp": 1743512400000
}
```

### Notes

`404 commodity symbol not supported` when the code is not in the curated registry. `404 no quote available` when no consolidated quote can be resolved. `503 service temporarily unavailable` when data cannot be retrieved temporarily.

## Last trade

**Endpoint:** `GET /commodities/trade/last/:symbol`

Most recent trade-like price for the symbol when present; otherwise a deterministic midpoint derived from the consolidated quote.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | Yes | Enabled commodity symbol (e.g. XAUUSD, WTIUSD). Trimmed and uppercased before lookup. Discover tickers with GET /commodities/symbols. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/trade/last/XAUUSD" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/trade/last/XAUUSD",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/commodities/trade/last/XAUUSD", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/commodities/trade/last/XAUUSD", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbol": "XAUUSD",
  "price": 2318.42,
  "size": 42,
  "timestamp": 1743512400000
}
```

### Notes

`404 symbol not available` when the code is not in the curated registry; `404 no fresh trade available` when no quote can be resolved.

## Snapshot

**Endpoint:** `GET /commodities/snapshot/:symbol`

Combined bid/ask, last price, previous daily close, and derived change metrics in one normalized commodity snapshot.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | Yes | Enabled commodity symbol (e.g. XAUUSD, WTIUSD). Trimmed and uppercased before lookup. Discover tickers with GET /commodities/symbols. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/snapshot/WTIUSD" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/snapshot/WTIUSD",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/commodities/snapshot/WTIUSD", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/commodities/snapshot/WTIUSD", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbol": "WTIUSD",
  "bid": 71.22,
  "ask": 71.25,
  "bid_size": 58,
  "ask_size": 55,
  "last_price": 71.235,
  "last_timestamp": 1743512400000,
  "prev_close": 70.90,
  "change": 0.335,
  "change_percent": 0.472
}
```

### Notes

`last_size` appears when a trade size is available in the consolidated snapshot; otherwise it is omitted from the payload. `change_percent` is `null` when `prev_close` is zero or unavailable. An unknown symbol or an all-null snapshot returns `404`.

## Previous bar

**Endpoint:** `GET /commodities/agg/:symbol/prev`

Single most-recently completed UTC daily candle for the symbol.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | Yes | Enabled commodity symbol (e.g. XAUUSD, WTIUSD). Trimmed and uppercased before lookup. Discover tickers with GET /commodities/symbols. |

### Query parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `interval` | string | Returns the most recently settled bar at that interval instead of the previous daily bar, and adds `interval`, `bar_start`, `bar_end` and `as_of` to the response. Leave it out for the daily bar. Values: `1m`, `5m`, `15m`, `1h`, `4h`, `1d`. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/agg/XAUUSD/prev" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/agg/XAUUSD/prev",
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch("https://api.tickerlayer.com/commodities/agg/XAUUSD/prev", {
  headers: { "x-api-key": "<YOUR_API_KEY>" },
});
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET", "https://api.tickerlayer.com/commodities/agg/XAUUSD/prev", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbol": "XAUUSD",
  "result": {
    "o": 2295.10,
    "h": 2325.40,
    "l": 2288.20,
    "c": 2318.42,
    "v": 0,
    "t": 1733011200000
  }
}
```

### Notes

`404 no bar available` when the daily bar cannot be resolved yet. A bar requested with `?interval=` is held for a short settle lag after it closes, so small clock differences between callers do not change which bar comes back, and it is the same bar the range endpoint returns for that window. `Cache-Control` and `ETag` mark when the value can next change. While the market is closed the last real bar is returned, still labelled with its own `bar_start`.

## Aggregate bars (OHLCV)

**Endpoint:** `GET /commodities/agg/:symbol/:multiplier/:timespan/:from/:to`

Historical bars between two UTC calendar dates.

### Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `symbol` | string | Yes | Enabled commodity symbol (e.g. XAUUSD, CORNUSD). Trimmed and uppercased before lookup. |
| `multiplier` | number | Yes | Bar size in units of `timespan`: `1`, `5` or `15` with `minute`; `1` or `4` with `hour`; `1` with `day`. Other pairs return `400`, and the message lists the valid ones. |
| `timespan` | string | Yes | Case-insensitive. Other values return `400`. Values: `minute`, `hour`, `day`. |
| `from` | string | Yes | First UTC date, inclusive, as `YYYY-MM-DD`. |
| `to` | string | Yes | Last UTC date, inclusive, as `YYYY-MM-DD`. Not before `from`. |

### Query parameters

| Parameter | Type | Description |
| --- | --- | --- |
| `limit` | number | Page size, up to `5000`. `results_count` is the size of this page and `total_count` the bars in the whole range; follow `next_offset` until it is `null`. Default: `500`. |
| `offset` | number | Zero-based row offset, applied after sorting. Default: `0`. |
| `sort` | string | Order of bars by timestamp `t`, applied before pagination. Values: `asc`, `desc`. Default: `desc`. |

### Request

```bash
curl -sS "https://api.tickerlayer.com/commodities/agg/XAUUSD/1/day/2025-11-01/2025-11-30?sort=desc&limit=2" \
  -H "x-api-key: <YOUR_API_KEY>"
```

```python
import requests

res = requests.get(
    "https://api.tickerlayer.com/commodities/agg/XAUUSD/1/day/2025-11-01/2025-11-30",
    params={"sort": "desc", "limit": 2},
    headers={"x-api-key": "<YOUR_API_KEY>"},
)
print(res.json())
```

```javascript
const res = await fetch(
  "https://api.tickerlayer.com/commodities/agg/XAUUSD/1/day/2025-11-01/2025-11-30?sort=desc&limit=2",
  { headers: { "x-api-key": "<YOUR_API_KEY>" } },
);
const data = await res.json();
console.log(data);
```

```go
req, _ := http.NewRequest("GET",
  "https://api.tickerlayer.com/commodities/agg/XAUUSD/1/day/2025-11-01/2025-11-30?sort=desc&limit=2", nil)
req.Header.Set("x-api-key", "<YOUR_API_KEY>")
```

### Response

```json
{
  "symbol": "XAUUSD",
  "results_count": 2,
  "results": [
    { "o": 2295.10, "h": 2325.40, "l": 2288.20, "c": 2318.42, "v": 0, "t": 1733011200000 },
    { "o": 2270.50, "h": 2305.00, "l": 2265.00, "c": 2295.10, "v": 0, "t": 1732924800000 }
  ],
  "next_offset": 2
}
```

### Notes

- One request covers at most 31 days of 1-minute bars, 90 of 5-minute, 180 of 15-minute, 365 of hourly, 730 of 4-hour and 5000 of daily bars, counting `from` and `to` as whole UTC days. A longer range returns `400` with the limit in the message.
- `v` is the aggregated volume for the bar. For energy, copper and the agricultural contracts it is the front-month futures contract's exchange volume over the bar's span; for the metals it comes from the aggregation layer. It is `null` when no volume is available for that bar, and `0` when the bar traded nothing.

## WebSocket

Stream live quotes and trades for this asset class over the public WebSocket.

**Connect**

```
wss://stream.tickerlayer.com/?apiKey=<YOUR_API_KEY>
```

### Available channels

- `commodities.quotes`: quotes
- `commodities.trades`: trades

### Subscribe example

After the connection is ready, send a JSON text frame:

```json
{
  "action": "subscribe",
  "channels": [
    "commodities.quotes",
    "commodities.trades"
  ],
  "symbols": [
    "XAUUSD",
    "WTIUSD"
  ]
}
```

### Example messages

**commodities.quotes**

```json
{
  "type": "quote",
  "channel": "commodities.quotes",
  "asset": "commodities",
  "symbol": "XAUUSD",
  "bid": 2318.1,
  "ask": 2318.74,
  "bid_size": 58,
  "ask_size": 48,
  "ts": 1743512400000,
  "timestamp": 1743512400000
}
```

**commodities.trades**

```json
{
  "type": "trade",
  "channel": "commodities.trades",
  "asset": "commodities",
  "symbol": "XAUUSD",
  "price": 2318.42,
  "size": 42,
  "ts": 1743512400000,
  "timestamp": 1743512400000
}
```

### General WebSocket documentation

For authentication, subscribe/unsubscribe lifecycle, errors, limits, and heartbeats, see the [WebSocket overview](https://tickerlayer.com/docs/websocket), [Subscriptions](https://tickerlayer.com/docs/websocket/subscriptions) and [Message types](https://tickerlayer.com/docs/websocket/messages).
