BlogDeveloper

Fetch live gold prices in JavaScript

Working code for pulling the gold spot price from the API in Node.js and the browser, with proper error handling.

16 Jul 2026 · 3 min read

Fetch live gold prices in JavaScript

The goldprice.dev API returns the current spot price in a single authenticated GET request. This post walks through a minimal working implementation in both Node.js and the browser, then covers the error cases worth handling.

Get a free API key via the quickstart guide. The free tier includes 5,000 calls per month and gold, silver, and copper spot, 15 minutes late.

The endpoint

Request
GET https://api.goldprice.dev/v1/spot/XAU-USD-SPOTAuthorization: Bearer ga_live_YOUR_KEY

The response is a flat JSON object:

JSON
{  "symbol": "XAU-USD-SPOT",  "price": 2387.45,  "currency": "USD",  "unit": "troy_oz",  "timestamp": "2026-06-19T08:32:11Z"}

Node.js (18+)

Node 18 ships with the fetch API, so no extra dependencies are needed.

JavaScript
const API_KEY = process.env.GOLDPRICE_API_KEY;const BASE_URL = "https://api.goldprice.dev";async function getGoldSpot() {  const res = await fetch(`${BASE_URL}/v1/spot/XAU-USD-SPOT`, {    headers: {      Authorization: `Bearer ${API_KEY}`,    },  });  if (!res.ok) {    const body = await res.text();    throw new Error(`API error ${res.status}: ${body}`);  }  return res.json();}getGoldSpot()  .then((data) => {    console.log(`Gold spot: $${data.price} USD/troy oz`);    console.log(`As of: ${data.timestamp}`);  })  .catch(console.error);

Run it:

Shell
GOLDPRICE_API_KEY=ga_live_your_key node gold.js

Never hardcode the key string in source files. Reading it from process.env is the minimum safe approach; for production, use a secrets manager or environment injection at deploy time.

Browser

The same fetch API works in the browser with one caveat: your API key must not be exposed to the client. If you are building a public-facing app, proxy the request through your own backend. The browser code calls your server, and your server calls the goldprice.dev API with the key.

For internal tools, dashboards, or demos where key exposure is acceptable:

JavaScript
async function getGoldSpot(apiKey) {  const res = await fetch("https://api.goldprice.dev/v1/spot/XAU-USD-SPOT", {    headers: {      Authorization: `Bearer ${apiKey}`,    },  });  if (!res.ok) {    throw new Error(`Request failed: ${res.status} ${res.statusText}`);  }  return res.json();}// UsagegetGoldSpot("ga_live_your_key").then((data) => {  document.getElementById("gold-price").textContent =    `$${data.price.toLocaleString()} USD/oz`;});

Error handling

Three HTTP status codes cover almost every failure case:

  • 401 Unauthorized: missing or invalid Authorization header. Check that the key is present and starts with ga_live_.
  • 429 Too Many Requests: rate limit exceeded. The response body includes a retry_after field in seconds. Back off and retry after that interval.
  • 5xx: server-side error. These are transient; retry with exponential backoff.

A more complete handler:

JavaScript
async function getGoldSpotSafe() {  let attempt = 0;  const maxAttempts = 3;  while (attempt < maxAttempts) {    const res = await fetch(      "https://api.goldprice.dev/v1/spot/XAU-USD-SPOT",      {        headers: { Authorization: `Bearer ${process.env.GOLDPRICE_API_KEY}` },      }    );    if (res.status === 401) {      throw new Error("Invalid API key. Check GOLDPRICE_API_KEY.");    }    if (res.status === 429) {      const body = await res.json();      const wait = (body.retry_after ?? 60) * 1000;      await new Promise((r) => setTimeout(r, wait));      attempt++;      continue;    }    if (!res.ok) {      const delay = Math.min(1000 * 2 ** attempt, 10000);      await new Promise((r) => setTimeout(r, delay));      attempt++;      continue;    }    return res.json();  }  throw new Error("Max retry attempts reached");}

Caching on the free tier

With 5,000 calls per month, you have roughly 166 calls per day, enough for a polling interval of around 9 minutes. If you need to display a frequently refreshing price, cache the response on your server and serve it to your front end from there. A simple in-memory cache with a 60-second TTL is enough for most use cases:

JavaScript
let cache = null;let cacheTime = 0;const TTL_MS = 60_000;async function getCachedGoldSpot() {  if (cache && Date.now() - cacheTime < TTL_MS) {    return cache;  }  cache = await getGoldSpot();  cacheTime = Date.now();  return cache;}

Paid plans provide live prices and higher monthly quotas. Keep caching and watch your rate-limit headers.

What's in the response

The price field is in USD per troy ounce. The timestamp is ISO 8601 in UTC. If you need the price in grams or other currencies, see Convert gold prices across currencies in code, that post covers the conversion arithmetic and a complete working example. The API documentation covers silver (XAG-USD-SPOT) and copper (HG-USD-SPOT), both available on every plan.

If you only need a price card on a website, use the free gold price widget instead. It is a hosted iframe with no browser-side API key, 31 currencies, gram and troy-ounce units, karat options, and built-in attribution.

Live gold prices, historical OHLC, and multi-source aggregation, available via REST and SSE.

Keep reading

Start with a free API key

5,000 requests a month on the free plan. No credit card.

Get a free key