Metals Intraday API: Hourly XAU Through One Day

Metals-API 4 min read
Metals Intraday API: Hourly XAU Through One Day

A metals intraday API returns one metal, one UTC date, and one interval. On Metals-API that is GET https://metals-api.com/api/intraday with query access_key. Live sample below: symbol=XAU, base=USD, date=2026-09-24, interval=1h.

The contract is date + interval + rates[timestamp].XAU. Map each key to { time, value }. Allowed intervals: 1m, 5m, 10m, 15m, 30m, 45m, 1h, 2h, 4h, 8h, 12h, 1d (default 1d). One symbol per call. symbol and base must differ. Docs: metals-api.com/documentation (Intraday).

Yesterday: hourly XAU

API request

curl "https://metals-api.com/api/intraday?access_key=YOUR_API_KEY&symbol=XAU&base=USD&date=2026-09-24&interval=1h"

Live body (pulled 25 Sep 2026). On this endpoint rates.XAU is already USD per ounce. Keys in this sample run 00:00–09:00 UTC. meta.update_rate is 60m.

JSON response

{
"rates": {
"2026-09-24T00:00:00Z": { "XAU": 4288.164665523156 },
"2026-09-24T01:00:00Z": { "XAU": 4297.378599054577 },
"2026-09-24T02:00:00Z": { "XAU": 4282.471842747634 },
"2026-09-24T03:00:00Z": { "XAU": 4291.108822519739 },
"2026-09-24T04:00:00Z": { "XAU": 4282.838665467472 },
"2026-09-24T05:00:00Z": { "XAU": 4288.900325956425 },
"2026-09-24T06:00:00Z": { "XAU": 4277.525879031568 },
"2026-09-24T07:00:00Z": { "XAU": 4276.977032633335 },
"2026-09-24T08:00:00Z": { "XAU": 4278.257893385813 },
"2026-09-24T09:00:00Z": { "XAU": 4260.576882109837 }
},
"meta": { "update_rate": "60m" },
"message": "If you request an interval smaller than the update rate, consecutive candles may repeat the same price until new data is available."
}

PHP: fetch and map

Useful part is the request and the { time, value } list — not a chart library. Drop $points into whatever you already plot with.

$url = 'https://metals-api.com/api/intraday?access_key=' . urlencode($access_key)
. '&symbol=XAU&base=USD&date=2026-09-24&interval=1h';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$payload = json_decode(curl_exec($ch), true);
curl_close($ch);

$points = [];
foreach ($payload['rates'] as $time => $row) {
$points[] = ['time' => $time, 'value' => $row['XAU']];
}
4,303.274,291.124,278.984,266.834,254.69 00:0001:0002:0003:0004:0005:0006:0007:0008:0009:00
Live interval=1h on 2026-09-24. High 4297.378599054577 at 01:00 UTC; last print 4260.576882109837 at 09:00 UTC.

Repeated ticks on 1m

Same date, interval=1m. 00:04 through 00:07 print the same 4289.452236949342 — that is a hold, not four moves. Those four points are marked in red.

API request

curl "https://metals-api.com/api/intraday?access_key=YOUR_API_KEY&symbol=XAU&base=USD&date=2026-09-24&interval=1m"

JSON response

{
"rates": {
"2026-09-24T00:00:00Z": { "XAU": 4288.164665523156 },
"2026-09-24T00:01:00Z": { "XAU": 4288.164665523156 },
"2026-09-24T00:02:00Z": { "XAU": 4288.34855697071 },
"2026-09-24T00:03:00Z": { "XAU": 4288.34855697071 },
"2026-09-24T00:04:00Z": { "XAU": 4289.452236949342 },
"2026-09-24T00:05:00Z": { "XAU": 4289.452236949342 },
"2026-09-24T00:06:00Z": { "XAU": 4289.452236949342 },
"2026-09-24T00:07:00Z": { "XAU": 4289.452236949342 },
"2026-09-24T00:08:00Z": { "XAU": 4288.164665523156 },
"2026-09-24T00:09:00Z": { "XAU": 4288.164665523156 }
},
"meta": { "update_rate": "1m" },
"message": "If you request an interval smaller than the update rate, consecutive candles may repeat the same price until new data is available."
}
4,289.664,289.234,288.814,288.384,287.96 00:0000:0100:0200:0300:0400:0500:0600:0700:0800:09
Live interval=1m on 2026-09-24, first ten minutes UTC. Red = the four-print hold at 4289.452236949342.

A month of daily closes: /timeseries

Intraday is one UTC day. For day-by-day over a window use GET /api/timeseries. end_date cannot be today — this sample ends on yesterday. Docs: Time-Series.

API request

curl "https://metals-api.com/api/timeseries?access_key=YOUR_API_KEY&start_date=2026-08-25&end_date=2026-09-24&symbols=XAU&base=USD"

Live body: 31 daily keys. With base=USD, rates[date].XAU is ounces per 1 USD — invert 1 / XAU for USD/oz. That is a different envelope from /intraday.

JSON response

{
"success": true,
"timeseries": true,
"start_date": "2026-08-25",
"end_date": "2026-09-24",
"base": "USD",
"rates": {
"2026-08-25": { "USD": 1, "XAU": 0.00021486892995273 },
"2026-08-26": { "USD": 1, "XAU": 0.00021637996321541 },
"2026-09-01": { "USD": 1, "XAU": 0.00023109098051903 },
"2026-09-23": { "USD": 1, "XAU": 0.00023311653495581997 },
"2026-09-24": { "USD": 1, "XAU": 0.0002344336084021 }
}
}

First print ≈ 4654.00 USD/oz (25 Aug). Last print ≈ 4265.60 (24 Sep). The [...] days are in the live call; the chart below uses all 31.

$url = 'https://metals-api.com/api/timeseries?access_key=' . urlencode($access_key)
. '&start_date=2026-08-25&end_date=2026-09-24&symbols=XAU&base=USD';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$payload = json_decode(curl_exec($ch), true);
curl_close($ch);

$points = [];
foreach ($payload['rates'] as $day => $row) {
$points[] = ['time' => $day, 'value' => 1 / $row['XAU']];
}
4,7164,5884,4604,3324,203 08-2508-3009-0409-0909-1409-1909-24
Live /timeseries, 25 Aug–24 Sep 2026. Y-axis is inverted 1 / rates[date].XAU (USD/oz).

Do not mix ISO XAU with LBMA (USDLBXAUPM). Intraday is not open/high/low/close — that is GET /api/open-high-low-close/{YYYY-MM-DD}.

Same key

  • GET /api/latest?symbols=XAU — spot; on latest, rates.USDXAU is USD/oz when base=USD.
  • GET /api/open-high-low-close/{date} — one UTC-day candle.

MCP: metals-api.com/mcp (metals.intraday, metals.time_series).

Go live

1. Register and copy access_key.

2. GET /api/intraday with yesterday’s date and an interval.

3. For a month, GET /api/timeseries and invert 1 / XAU when base=USD.

4. If two timestamps share a price, keep both.

Read hourly XAU with a Metals key →