XAU
---.--
--.--
XAG
---.--
--.--
XPT
---.--
--.--
XPD
---.--
--.--
HG
---.--
--.--
ALI
---.--
--.--
NI
---.--
--.--
ZN
---.--
--.--
PB
---.--
--.--
SN
---.--
--.--
JBP
---.--
--.--
LC
---.--
--.--
UXA
---.--
--.--
XAU
---.--
--.--
XAG
---.--
--.--
XPT
---.--
--.--
XPD
---.--
--.--
HG
---.--
--.--
ALI
---.--
--.--
NI
---.--
--.--
ZN
---.--
--.--
PB
---.--
--.--
SN
---.--
--.--
JBP
---.--
--.--
LC
---.--
--.--
UXA
---.--
--.--

Free Metals Price API

Live gold, silver, platinum, palladium and copper prices as JSON, free and without a credit card. The free tier allows 1,000 requests a month, which is roughly 33 a day, and it does not expire into a trial.

What the free tier includes, and what it does not

Stated plainly, because a free tier that hides its limits until you have written the integration is worse than no free tier.

Included

  • Live spot prices for gold, silver, platinum, palladium and copper
  • Aluminium, nickel, zinc, lead and tin
  • Bid, ask, 24-hour change, high and low on every quote
  • Currency conversion across major pairs
  • Market status, so you know whether a venue is open
  • The full instrument catalogue, 1,100 plus symbols

Needs a paid plan

  • Historical prices and candles, which start on Basic
  • News, futures, crypto, ETFs and indices
  • COMEX, LBMA, Shanghai and India exchange data
  • CFTC positioning, funding rates and bullion dealer premiums

Free is live prices only by design. Those are served from cache and cost us almost nothing, which is why the allowance can be generous rather than a token. History and exchange data are expensive to collect and keep correct, so they sit behind a plan.

Code examples

Each example fetches the live gold price and prints it. There is no SDK to install: the API is plain HTTPS returning JSON, so whatever HTTP client you already use will do.

Gold price in Python

import requests

res = requests.get(
    "https://api.metalcharts.org/v1/prices",
    headers={"Authorization": "Bearer mc_live_YOUR_KEY"},
    timeout=10,
)
res.raise_for_status()

price = res.json()["data"]["XAU"]["price"]
print(f"Gold: ${price}")

Uses requests. raise_for_status turns a 401 or 429 into an exception rather than letting a bad payload through.

Gold price in JavaScript

const res = await fetch(
  "https://api.metalcharts.org/v1/prices",
  { headers: { Authorization: "Bearer mc_live_YOUR_KEY" } },
);

if (!res.ok) throw new Error(`HTTP ${res.status}`);

const { data } = await res.json();
console.log(`Gold: ${data.XAU.price}`);

Native fetch, so it runs in Node 18 and above and in the browser. Never ship a key to the browser; proxy through your own server.

Gold price in PHP

<?php
$ch = curl_init("https://api.metalcharts.org/v1/prices");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer mc_live_YOUR_KEY"],
    CURLOPT_TIMEOUT => 10,
]);

$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($code !== 200) {
    throw new RuntimeException("MetalCharts API returned $code");
}

$data = json_decode($body, true);
echo "Gold: " . $data["data"]["XAU"]["price"];

Plain cURL with no dependencies. Checking the status code matters because a failed call still returns a parseable body.

Gold price in Go

req, _ := http.NewRequest(
    http.MethodGet, "https://api.metalcharts.org/v1/prices", nil,
)
req.Header.Set("Authorization", "Bearer mc_live_YOUR_KEY")

resp, err := http.DefaultClient.Do(req)
if err != nil {
    return err
}
defer resp.Body.Close()

var out struct {
    Data map[string]struct {
        Price float64 `json:"price"`
    } `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
    return err
}
fmt.Println("Gold:", out.Data["XAU"].Price)

Decoding into a narrow struct rather than a map keeps the compiler honest about the field you actually use.

Replace mc_live_YOUR_KEY with a key from the API console. The free tier needs an account but not a card.

How the limits work

Two limits apply: 10 weight a minute and 1,000 a month. Most calls cost 1 weight. Requests carry X-RateLimit-Remaining and X-RateLimit-Month-Remaining so you can see both budgets without guessing.

Going over returns a 429 with the reset time rather than a silent failure or a truncated payload. Nothing is charged automatically and no plan upgrades itself.

Free API questions

Is the metals API really free?

Yes, and it does not expire. The free tier gives live spot prices for every metal we track, currency conversion and market status, with one API key and 1,000 weight a month. You need an account but not a credit card, and there is no trial clock.

How many requests does the free tier allow?

1,000 weight a month and 10 weight a minute. Spot price calls cost 1 weight each, so that is about 1,000 price requests a month, or roughly 33 a day. That comfortably covers evaluating the API and running a small embedded widget. Anything polling every fifteen minutes needs a paid plan, since that alone is close to 3,000 requests a month.

What is not included in the free tier?

Historical data, news, futures, crypto, ETFs and indices all need a paid plan, as does exchange data such as COMEX inventory and CFTC positioning. Free is deliberately live prices only, because that is the part that costs us almost nothing to serve from cache.

Do I need a credit card for the free tier?

No. Create an account, open the API console and generate a key. Nothing asks for payment details unless you choose a paid plan.

How does this compare to other free metals APIs?

Most free tiers in this category cap you at 50 to 100 requests a month. This one allows 1,000, covers ten metals rather than two, returns bid and ask, and includes currency conversion, which usually sits behind a paid plan elsewhere.

Can I use the free tier commercially?

Yes. Commercial use is permitted on every plan, the free tier included, and there is no separate commercial licence to buy. You can put free-tier prices on a commercial site. The restriction that applies to every plan is that you may not resell access to the API or republish the raw data as a competing feed.