Para obtener precios del oro en tiempo real en Node.js, envía un GET a api.goldprice.dev/v1/spot/XAU-USD-SPOT con tu clave en la cabecera X-API-Key. Usa fetch nativo, sin bibliotecas HTTP.
Guarda la respuesta en un Map durante 60 segundos y calcula con decimal.js. El plan gratuito incluye 5.000 consultas/mes, sin tarjeta. Probado en julio de 2026 con Node 22 LTS.
Obtén tu clave de API de goldprice.dev
Crea una cuenta gratuita en goldprice.dev/onboarding. Tras confirmar tu correo, verás en tu panel una clave que empieza por ga_live_. Guárdala como variable de entorno:
export GOLDPRICE_API_KEY=ga_live_replace_with_your_key_hereEl plan gratuito incluye 5.000 consultas/mes y precios al contado del oro en 31 monedas. No necesitas tarjeta.
Instala decimal.js
Node 18+ incluye fetch nativo, así que no necesitas un cliente HTTP. La única dependencia es decimal.js, que permite calcular precios con precisión y evita los errores del tipo Number de JavaScript. Instálala:
npm install decimal.jsEscribe el cliente de goldprice
Guarda este código como goldprice.mjs. La función spot() almacena cada símbolo durante 60 segundos en un Map, reintenta hasta 3 veces ante 429 con esperas exponenciales y devuelve precios como Decimal. Los precios opcionales de compra y venta solo están disponibles en planes de pago y quedan en null si faltan.
// node: goldprice.mjs// curl-equivalent: https://api.goldprice.dev/v1/spot/XAU-USD-SPOTimport Decimal from "decimal.js";const API_BASE = "https://api.goldprice.dev";const API_KEY = process.env.GOLDPRICE_API_KEY;if (!API_KEY) { throw new Error("GOLDPRICE_API_KEY not set");}const TTL_MS = 60_000;const cache = new Map();/** Fetch live spot price. Cached 60s per symbol, retries 3x on 429. */export async function spot(symbol = "XAU-USD-SPOT") { const cached = cache.get(symbol); if (cached && cached.expiresAt > Date.now()) { return cached.data; } let lastErr; for (let attempt = 0; attempt < 3; attempt++) { const res = await fetch(`${API_BASE}/v1/spot/${symbol}`, { headers: { "X-API-Key": API_KEY }, signal: AbortSignal.timeout(5000), }); if (res.status === 429) { lastErr = new Error("goldprice: 429 rate limited"); const backoffMs = 2 ** attempt * 1000; // 1s, 2s, 4s await new Promise((resolve) => setTimeout(resolve, backoffMs)); continue; } if (!res.ok) { throw new Error(`goldprice: unexpected status ${res.status}`); } const raw = await res.json(); const data = { symbol: raw.symbol, quoteCurrency: raw.quote_currency, price: new Decimal(raw.price), bid: raw.bid == null ? null : new Decimal(raw.bid), ask: raw.ask == null ? null : new Decimal(raw.ask), isStale: raw.is_stale, computedAt: raw.computed_at, }; cache.set(symbol, { data, expiresAt: Date.now() + TTL_MS }); return data; } throw lastErr;}Ejecútalo
Importa el módulo y llama a spot(). La primera llamada consulta la API; durante 60 segundos, las siguientes devuelven el Decimal en caché sin acceder a la red. Reiniciar el proceso borra la caché. Usa Redis si necesitas compartirla entre procesos.
import { spot } from "./goldprice.mjs";const r = await spot("XAU-USD-SPOT");console.log(`${r.symbol}-${r.quoteCurrency}: ${r.price} (computed ${r.computedAt})`);// XAU-USD: 4012.75 (computed 2026-10-23T07:00:18.221118+00:00)Cambia de moneda o metal
Los símbolos siguen el formato METAL-CURRENCY-SPOT. Pasa a spot() cualquier símbolo de las 31 monedas al contado. Cada símbolo tiene su propia caché en el Map. Un panel que consulta 5 símbolos cada 60 segundos hace 5 llamadas/minuto sin caché y 0 si están en caché.
// USD spot, defaultawait spot("XAU-USD-SPOT");await spot("XAU-INR-SPOT");await spot("XAU-EUR-SPOT");// Silver in USDawait spot("XAG-USD-SPOT");Resultado esperado
{ "symbol": "XAU", "quote_currency": "USD", "unit": "troy_ounce", "contract_type": "spot", "price": "4012.75", "is_stale": false, "computed_at": "2026-10-23T07:00:18.221118+00:00"}La salida estándar muestra una línea: símbolo, moneda de cotización, precio como Decimal de decimal.js y fecha y hora computedAt en formato ISO 8601. Tu código utiliza el objeto que devuelve spot().
Errores comunes
| Código | Qué ves | Solución |
|---|---|---|
| 401 | goldprice: unexpected status 401 en la primera llamada | Falta la clave de API o no es válida. Comprueba la variable: echo $GOLDPRICE_API_KEY. Si está vacía, vuelve a exportarla desde tu panel. El módulo lanza un error al importarse si la variable está vacía, para que puedas detectarlo de inmediato. |
| 429 | Los tres reintentos con esperas devuelven 429 y spot() termina con un rechazo | Has alcanzado el límite por minuto. La caché de 60 segundos lo evita en consultas regulares. Si llegan muchos símbolos distintos a la vez, escalona las llamadas. Para un volumen elevado y continuo, consulta los planes de pago en /pricing. |
| N/A | Los precios parecen correctos, pero pierden precisión tras varios cálculos | Number de JavaScript usa coma flotante IEEE-754: 0.1 + 0.2 === 0.30000000000000004. Los precios del oro tienen 2 decimales; sumar miles con Number introduce errores de puntos básicos. Calcula con Decimal de decimal.js y llama a .toString() o .toNumber() solo al mostrar o serializar. |
Más opciones
- Comparte la caché entre procesos: sustituye el
Mappor Redis para que varios procesos reutilicen el precio almacenado - Añade una función
bars()para/v1/bars?symbol=XAU-USD-SPOT&interval=1d&from=...&to=...y usa la serie para probar una estrategia con datos históricos - Integra el cliente en una ruta de Express o Fastify y ofrece acceso interno a servicios que no usen Node
- Agrupa las solicitudes simultáneas del mismo símbolo sin caché para que generen una sola consulta
- Expón métricas de Prometheus sobre aciertos de caché, latencia p50/p95 y reintentos ante 429