Detect cross-source price divergence in code
Read per-source prices from the API response, compute the spread in basis points, and flag when sources disagree beyond your tolerance threshold.
Read →How to convert a USD per troy ounce gold price into other currencies and per-gram units, with a working JavaScript example.
Gold is normally quoted in US dollars per troy ounce, while an application may need rupiah per gram, yen per kilogram, or another local convention. You can either let goldprice.dev perform the whole conversion or fetch the gold and FX legs separately when you need to audit each source.
If you are new to the weight conventions, Troy ounce, gram, kilo: gold weight units explained covers the fixed conversion constants used below.
GET /v1/convert converts a metal amount into any supported currency and does not require an API key. This request asks for the value of one gram of gold in Indonesian rupiah:
const params = new URLSearchParams({
from: "XAU",
to: "IDR",
amount: "1",
unit: "gram",
});
const response = await fetch(
`https://api.goldprice.dev/v1/convert?${params}`,
);
if (!response.ok) {
throw new Error(`goldprice.dev returned ${response.status}`);
}
const conversion = await response.json();
console.log(conversion);
The endpoint combines the live gold price with the current currency rate server-side. Its single timestamp follows the gold spot leg and does not independently evidence FX freshness. Use this path when the final converted value is what your product needs; use the separate-leg path below when either input's provenance matters.
Fetch each leg yourself when you need separate timestamps, source labels, or control over caching. The gold leg comes from goldprice.dev; the USD exchange-rate leg comes from exchangerate.dev's latest-rates endpoint.
const GRAMS_PER_TROY_OZ = 31.1035;
async function getGoldInCurrencies(currencies) {
const symbols = currencies.join(",");
const [spotResponse, fxResponse] = await Promise.all([
fetch("https://api.goldprice.dev/v1/spot/XAU-USD-SPOT"),
fetch(`https://api.exchangerate.dev/v1/latest/USD?symbols=${symbols}`),
]);
if (!spotResponse.ok) {
throw new Error(`goldprice.dev returned ${spotResponse.status}`);
}
if (!fxResponse.ok) {
throw new Error(`exchangerate.dev returned ${fxResponse.status}`);
}
const spot = await spotResponse.json();
const fx = await fxResponse.json();
const usdPerGram = Number(spot.price) / GRAMS_PER_TROY_OZ;
return {
goldComputedAt: spot.computed_at,
fxDataUpdatedAt: fx.data_updated_at,
fxResponseTimestamp: fx.timestamp,
fxSource: fx.source,
fxMarketSession: fx.market_session,
prices: Object.fromEntries(
currencies.map((currency) => [
currency,
usdPerGram * Number(fx.rates[currency]),
]),
),
};
}
const result = await getGoldInCurrencies(["EUR", "IDR", "JPY"]);
console.log(result);
This keeps the two market observations explicit:
local_gold_per_gram = usd_gold_per_troy_ounce / 31.1035 * usd_to_local_rate
Do not silently replace the observation times with the time your application fetched the responses. computed_at describes the gold observation; data_updated_at is the oldest FX observation contributing to the rate. The FX timestamp is when that API response was built, while source and market_session explain its data class and session state.
Keep full numeric precision during the calculation, then format the final value for the user's locale:
function formatPrice(amount, currency, locale) {
return new Intl.NumberFormat(locale, {
style: "currency",
currency,
}).format(amount);
}
console.log(formatPrice(result.prices.IDR, "IDR", "id-ID"));
console.log(formatPrice(result.prices.JPY, "JPY", "ja-JP"));
The currency code and locale are independent. Choose the locale based on the reader, not the currency being displayed. Intl.NumberFormat applies the currency's standard minor units automatically.
Gold and currency data can refresh at different times. Cache each API response according to its own freshness fields instead of treating the combined number as one observation. Before displaying or acting on a value:
computed_at and FX data_updated_at observation times;timestamp, source, and market_session for diagnostics;For a deeper implementation with formulas and failure handling, see How to calculate gold prices in local currencies. Start with the goldprice.dev quickstart if you have not fetched a gold price yet.
related guides
Read per-source prices from the API response, compute the spread in basis points, and flag when sources disagree beyond your tolerance threshold.
Read →Add a free, configurable live gold price widget to WordPress with one iframe. Works in Gutenberg and Elementor, no API key, no plugin.
Read →Working code for pulling the gold spot price from the API in Node.js and the browser, with proper error handling.
Read →goldprice.dev
Live gold prices, historical OHLC, and multi-source aggregation — available via REST and SSE.