Real-time gold price API
Gold, silver, platinum and palladium prices pushed to your server as they change. You open one HTTPS connection and read events from it, with no polling loop and no quota spent per update.
A few seconds
between gold updates while the market is open
1 connection
on Pro, $99/month
10 connections
on Ultimate
1 request
to open a connection; the events aren't counted
Try it from a terminal
-N stops curl buffering, so events print as they arrive. Leave out symbols to get every metal, and add currency=EUR, unit=g or karat=22 to convert, exactly as on /v1/prices.cURL
curl -N -H "Authorization: Bearer mc_live_YOUR_KEY" \
"https://api.metalcharts.org/v1/stream/prices?symbols=XAU,XAG"What comes down the connection
First a
snapshot with every metal you asked for, then a price event each time one changes. Each quote has the same fields as a /v1/prices quote. A : ping comment line arrives every 15 seconds so proxies keep the connection open, and the server closes it after an hour, so reconnect when it ends.text/event-stream
retry: 5000
event: snapshot
data: {"data":{"XAU":{"symbol":"XAU","price":4102.35,"timestamp":"2026-11-12T14:03:05.271Z",...},"XAG":{...}},"timestamp":"2026-11-12T14:03:06.002Z"}
event: price
data: {"symbol":"XAU","price":4102.61,"timestamp":"2026-11-12T14:03:10.284Z","changePercent24h":0.41,...}
: pingLive gold prices in Python
Python
import json, os
import httpx
url = "https://api.metalcharts.org/v1/stream/prices"
headers = {"Authorization": f"Bearer {os.environ['METALCHARTS_API_KEY']}"}
while True: # the server closes each connection after an hour
with httpx.stream("GET", url, params={"symbols": "XAU,XAG"}, headers=headers, timeout=60) as res:
event = None
for line in res.iter_lines():
if line.startswith("event: "):
event = line[7:]
elif line.startswith("data: ") and event == "price":
quote = json.loads(line[6:])
print(quote["symbol"], quote["price"], quote["timestamp"])Polling works on every plan
The stream saves you a loop, but the prices are the same ones
/v1/prices returns on every plan, Free included. One request returns every metal and the response is at most 30 seconds old, so polling once a minute gets you within a minute of the market for about 43,000 requests a month. That fits Basic. The free plan covers 200 requests a month, enough to build and test against.FAQ
Common questions
Is there a free real-time gold price API?
The free plan reads the same live feed as every paid plan, by polling: /v1/prices returns every metal in one request, cached for at most 30 seconds, and the free allowance is 200 requests a month. The pushed stream starts on Pro at $99 a month.
Is this a WebSocket?
No, it's Server-Sent Events: a long-lived HTTPS response the server keeps writing to. Prices only flow one way, which is what SSE is for, and it works through proxies and load balancers with any HTTP client. If your code already speaks WebSocket, the change is small: read lines instead of frames.
How fresh are the prices?
Gold, silver, platinum and palladium change every few seconds while the market is open, and a change reaches the stream within about two seconds of reaching us. Base metals change less often. Every quote carries its own timestamp.
Does the stream count against my monthly allowance?
Opening a connection counts as one request. The events after that are not counted, however many there are.
How many connections can I open?
Pro holds 1 connection at a time, Ultimate 10 connections and Enterprise 50 connections, across all of an account's keys. One connection can carry every metal, so most apps need one, plus a second for a standby server.
Can I connect from a browser?
Don't put the key in browser code, where anyone can copy it. Open the stream on your server and pass prices on to your own users from there. The terms allow showing the data in your own product on every plan.
Stream prices from the Pro plan
Pro holds 1 connection along with COMEX, Shanghai and 5 years of history. Ultimate holds 10 connections and the full price record.