API de precios del oro: la guía completa para desarrolladores
Cómo usar una API de precios del oro: obtén una clave, llámala desde curl, JavaScript y Python, lee bien las cotizaciones y gestiona historial, errores, cuotas y caché.
Qué te ofrece una API de precios del oro
Una API de precios del oro devuelve el precio actual e histórico del oro como datos estructurados, normalmente JSON sobre HTTPS, para que tu software pueda usarlo sin extraer datos de páginas web ni copiar cifras a mano. En MetalAPI, el oro tiene el símbolo XAU, el código ISO 4217 de una onza troy de oro. Su precio en tiempo real es el precio al contado: el punto medio entre las cotizaciones interbancarias de compra (bid) y de venta (ask).
La mayoría de las integraciones no son sistemas de trading. Los usos típicos son estos:
- Tiendas online y joyerías que actualizan el precio de sus productos de oro según se mueve el mercado.
- Calculadoras de oro para fundir, joyería por quilates o primas de lingotes.
- Aplicaciones de seguimiento de carteras y de finanzas personales que valoran tenencias en una divisa local.
- Sistemas contables y ERP que revalorizan el inventario a un precio de cierre diario.
- Paneles, boletines e informes internos que necesitan un gráfico del último año.
La misma API cubre la plata (XAG), el platino (XPT) y el paladio (XPD), cuatro metales industriales, cinco contratos de energía, 57 divisas y 13 criptomonedas: 83 símbolos en total, todos ellos en la página de símbolos. Esta guía se centra en el oro, pero todo lo que contiene se aplica también a los demás símbolos.
Obtén una clave API
Crea una cuenta gratuita. El plan Free no requiere tarjeta de crédito e incluye 100 solicitudes al mes con actualización diaria de precios, suficiente para crear y probar una integración. Los planes de pago añaden precios más recientes, más solicitudes y endpoints adicionales; la tabla de planes de más abajo los resume.
En el panel, abre API keys y crea una clave. Las claves empiezan por mk_live_. La clave completa solo se muestra una vez, porque solo se almacena un hash de ella, así que guárdala de inmediato en una variable de entorno o en un gestor de secretos:
export METALAPI_KEY="mk_live_your_key_here"La API acepta la clave de tres formas equivalentes: un parámetro de consulta api_key, una cabecera Authorization: Bearer o una cabecera X-API-Key. En producción, es preferible usar una cabecera, porque las URL completas suelen acabar en registros de acceso, proxies y herramientas de seguimiento de errores. La guía de autenticación también explica las claves restringidas por dominio para llamadas desde el navegador.
# 1. Parámetro de consulta
curl "https://metalapi.com/api/v1/latest?api_key=$METALAPI_KEY¤cies=XAU"
# 2. Cabecera Authorization
curl "https://metalapi.com/api/v1/latest?currencies=XAU" \
-H "Authorization: Bearer $METALAPI_KEY"
# 3. Cabecera X-API-Key
curl "https://metalapi.com/api/v1/latest?currencies=XAU" \
-H "X-API-Key: $METALAPI_KEY"Tu primera solicitud con curl, JavaScript y Python
Cada endpoint es una simple solicitud GET bajo https://metalapi.com/api/v1/. El endpoint /latest devuelve los precios actuales. base establece la divisa en la que se expresan los precios (por defecto, USD) y currencies limita la respuesta a los símbolos que necesitas. Una solicitud puede devolver muchos símbolos y aun así cuenta como una sola solicitud.
curl "https://metalapi.com/api/v1/latest?base=USD¤cies=XAU,XAG" \
-H "X-API-Key: $METALAPI_KEY"Una respuesta correcta tiene este aspecto. Las cifras son los valores de ejemplo que se usan en toda la documentación de MetalAPI, no precios en tiempo real:
{
"success": true,
"timestamp": 1792834892,
"date": "2026-10-24",
"base": "USD",
"rates": {
"XAU": 0.0002501319,
"USDXAU": 3997.89,
"XAG": 0.0185392857,
"USDXAG": 53.94
},
"rate_limit": {
"limit": 10000,
"remaining": 9876,
"reset": 1793491200,
"used": 124,
"plan": "Standard",
"reset_date": "2026-11-01T00:00:00.000Z"
}
}La misma llamada desde Node.js 18 o posterior, que incluye fetch de serie. Guárdala como gold.mjs para que funcione el await de nivel superior y ejecuta node gold.mjs:
const params = new URLSearchParams({ base: "USD", currencies: "XAU,XAG" });
const res = await fetch(`https://metalapi.com/api/v1/latest?${params}`, {
headers: { Authorization: `Bearer ${process.env.METALAPI_KEY}` },
signal: AbortSignal.timeout(10_000),
});
const data = await res.json();
if (!data.success) {
throw new Error(`MetalAPI ${data.error.code} (${data.error.type}): ${data.error.info}`);
}
const gold = data.rates[`${data.base}XAU`];
const asOf = new Date(data.timestamp * 1000).toISOString();
console.log(`Gold: ${gold} ${data.base} per troy ounce (data from ${asOf})`);Y desde Python con la biblioteca requests:
import os
import requests
resp = requests.get(
"https://metalapi.com/api/v1/latest",
params={"base": "USD", "currencies": "XAU,XAG"},
headers={"X-API-Key": os.environ["METALAPI_KEY"]},
timeout=10,
)
data = resp.json()
if not data["success"]:
err = data["error"]
raise RuntimeError(f"MetalAPI {err['code']} ({err['type']}): {err['info']}")
base = data["base"]
print(f"Gold: {data['rates'][base + 'XAU']} {base} per troy ounce")
print(f"Silver: {data['rates'][base + 'XAG']} {base} per troy ounce")Ambos fragmentos construyen la clave de la cotización a partir de data.base en lugar de escribirla a mano. Esa pequeña costumbre mantiene el código correcto cuando más adelante cambias la divisa base, y nos lleva a la parte más importante de esta guía.
Interpreta correctamente el formato de las cotizaciones
Cada símbolo aparece dos veces en rates, y las dos cifras son inversas entre sí:
| Clave | Significado | Valor de ejemplo |
|---|---|---|
USDXAU | Precio de una onza troy de oro en la divisa base (USD) | 3997.89 |
XAU | Onzas troy de oro que se compran con una unidad de la divisa base | 0.0002501319 |
La regla general: rates.<BASE><SYMBOL> es el precio de una unidad del símbolo en la divisa base. La clave simple rates.<SYMBOL> es la inversa: unidades del símbolo por cada unidad de la base. La forma inversa se mantiene por compatibilidad con las API de estilo forex y con las integraciones antiguas de MetalAPI.
El error más común en las integraciones de precios del oro es leer rates.XAU y tratarlo como el precio. Es 1 ÷ precio, así que una ficha de producto muestra 0,00025 en lugar de 3997,89, y cualquier cálculo que multiplique por ese valor se equivoca en muchos órdenes de magnitud. Lee la clave con prefijo, como rates.USDXAU o rates.EURXAU.
Si ya guardas valores inversos de una integración antigua, no tienes que volver a descargarlos: precio = 1 ÷ inverso. Con el ejemplo anterior, 1 ÷ 0,0002501319 vuelve a dar 3997,89, salvo por las últimas cifras del redondeo.
Las divisas siguen la misma regla. Con base USD, USDEUR es el precio de un euro en dólares y EUR es la cantidad de euros por dólar. La guía de formatos de datos tiene más ejemplos, incluidas las claves bid y ask disponibles en el plan Standard y superiores.
Divisas base y unidades
Para obtener el precio del oro en otra divisa, cambia base. La clave de la cotización cambia con ella: base=EUR devuelve EURXAU, y base=INR devuelve INRXAU. Las cotizaciones cruzadas proceden de una misma instantánea, así que el oro en euros y el euro en dólares siempre son coherentes entre sí.
Los precios de los metales son por onza troy de forma predeterminada. El parámetro unit los devuelve por otra unidad de peso:
| unit | Precio por | Uso habitual |
|---|---|---|
troy_oz (por defecto) | Onza troy, 31,1034768 g | Cotizaciones de lingotes |
gram | Gramo | Joyería y venta al público |
kilogram | Kilogramo | Lingotes de un kilo, mercado mayorista |
ounce | Onza avoirdupois, 28,349523125 g | Rara vez adecuada para el oro |
pound | Libra avoirdupois | Cobre |
metric_ton | Tonelada métrica (1000 kg) | Aluminio, zinc |
short_ton | Tonelada corta (2000 lb) | Acero (HRC) |
Esta solicitud devuelve el oro y la plata en euros por gramo. Cuando unit no es el valor por defecto, la respuesta lo repite en un campo unit de nivel superior:
curl "https://metalapi.com/api/v1/latest?base=EUR¤cies=XAU,XAG&unit=gram" \
-H "X-API-Key: $METALAPI_KEY"unit=ounce (y su forma abreviada oz) es la onza avoirdupois, aproximadamente un 8,9 % más ligera que una onza troy. Para precios de lingotes, omite unit o pasa troy_oz.
unit solo afecta a los metales preciosos e industriales. La energía, las divisas y las criptomonedas no cambian. Para conocer los detalles sobre onzas troy, gramos, tolas y redondeo, lee Onzas troy, gramos y kilogramos. Si vendes joyería, Precios del oro por quilate explica los precios de 22K y 18K y el endpoint /carat.
Precios históricos del oro
Los precios pasados usan los mismos parámetros y el mismo formato de respuesta. El historial empieza en 2000 para los metales y la energía, el 4 de enero de 1999 para las divisas y en 2014 para las criptomonedas. Cuatro endpoints cubren la mayoría de las necesidades:
/YYYY-MM-DD(o/historical?date=YYYY-MM-DD, o/yesterday): precios de cierre de un día. Para los fines de semana y festivos, se devuelve el cierre del día de negociación más reciente./timeframe(alias/timeseries): cierres diarios entrestart_dateyend_date, hasta 30 días por solicitud en Free y 365 días en los planes de pago./change: cotización inicial, cotización final, variación absoluta y variación porcentual entre dos fechas./ohlc: apertura, máximo, mínimo y cierre de un día.
# Oro y plata al cierre del 15 de enero de 2024
curl "https://metalapi.com/api/v1/2024-01-15?currencies=XAU,XAG" \
-H "X-API-Key: $METALAPI_KEY"
# Cierres diarios del oro en euros de septiembre de 2026
curl "https://metalapi.com/api/v1/timeframe?start_date=2026-09-01&end_date=2026-09-30&base=EUR¤cies=XAU" \
-H "X-API-Key: $METALAPI_KEY"Los precios de cierre de los días pasados no cambian, así que guárdalos una vez en lugar de volver a pedirlos. Precios históricos del oro y la plata por API explica paso a paso cómo paginar 25 años de datos, guardarlos localmente y representarlos en gráficos. La guía de datos históricos incluye una función auxiliar en JavaScript para rangos largos.
Errores, cuotas y límites de los planes
Una solicitud fallida devuelve un código de estado HTTP de error y un cuerpo con success: false. El objeto error tiene un code numérico, un type legible por máquinas y un info legible por personas. Decide qué hacer según code o type, nunca según el texto de info. Los errores de límite por minuto (104), cuota (105), restricción del plan (106) y periodo (207) también incluyen una upgrade_url:
{
"success": false,
"error": {
"code": 106,
"type": "plan_restriction",
"info": "The carat endpoint requires a paid subscription plan",
"upgrade_url": "https://metalapi.com/dashboard/billing"
}
}Los códigos que es más probable que encuentres:
| Código | Tipo | HTTP | Qué hacer |
|---|---|---|---|
101, 102 | no_api_key, invalid_api_key | 401 | Envía una clave válida y revisa tu variable de entorno |
104 | too_many_requests | 429 | Espera los segundos de Retry-After y vuelve a intentarlo |
105 | quota_exceeded | 429 | Cuota mensual agotada; se restablece el día 1 (UTC) |
106 | plan_restriction | 403 | Endpoint o parámetro no incluido en tu plan |
205 | invalid_date | 400 | Corrige una fecha mal formada o futura |
207 | timeframe_too_long | 400 | Divide el rango en solicitudes más cortas |
300 | no_results | 404 | Sin datos, por ejemplo antes del inicio del historial |
500, 503 | server_error, service_unavailable | 500, 503 | Reintenta con espera exponencial |
Cada respuesta autenticada informa de tu cuota, tanto en las cabeceras X-RateLimit-* como en el objeto rate_limit del cuerpo. /usage y /symbols nunca cuentan para la cuota, así que tu sistema de monitorización puede llamarlos libremente. Las solicitudes rechazadas con 104, 106, 107 o con un error del servidor no se facturan, pero los errores de validación sí. La guía de manejo de errores enumera todos los códigos e incluye una función auxiliar de reintentos.
Los planes se diferencian sobre todo en el volumen de solicitudes y en lo recientes que son los precios:
| Plan | Precio / mes | Solicitudes / mes | Actualizaciones | Añade |
|---|---|---|---|---|
| Free | 0 USD | 100 | Diarias | Rangos de 30 días |
| Lite | 4,99 USD | 1000 | 30 min | Precios por quilate, rangos de 365 días |
| Standard | 11,99 USD | 10.000 | 10 min | Precios bid/ask |
| Advanced | 24,99 USD | 50.000 | 1 min | Alertas por webhook |
| Pro | 49,99 USD | 100.000 | 1 min | Stream en tiempo real |
| Ultra | 99,99 USD | 500.000 | 15 s | Mayor volumen |
| Business | 149,99 USD | 500.000 | 15 s | SLA de disponibilidad |
| Enterprise | 299,99 USD | 1.500.000 | 5 s | Máximo volumen |
La facturación anual ahorra hasta un 25 %. La página de precios siempre tiene los detalles actualizados.
Caché y consejos para producción
Solicitar /latest con más frecuencia de la que se actualiza tu plan devuelve las mismas cifras y gasta cuota para nada. Guarda en caché los últimos precios durante al menos el intervalo de actualización de tu plan, y guarda los días pasados de forma permanente. Esta función auxiliar en Python guarda en caché los últimos precios y sigue sirviendo la última respuesta válida si no se puede contactar con la API:
import os
import time
import requests
TTL_SECONDS = 600 # Plan Standard: los precios se actualizan cada 10 minutos
session = requests.Session()
session.headers["X-API-Key"] = os.environ["METALAPI_KEY"]
_cache = {"at": 0.0, "data": None}
def latest_prices():
now = time.monotonic()
if _cache["data"] and now - _cache["at"] < TTL_SECONDS:
return _cache["data"]
try:
r = session.get(
"https://metalapi.com/api/v1/latest",
params={"currencies": "XAU,XAG,XPT,XPD"},
timeout=10,
)
data = r.json()
except (requests.RequestException, ValueError):
data = None
if data and data.get("success"):
_cache.update(at=now, data=data)
return data
if _cache["data"]:
return _cache["data"] # últimos precios válidos; muestra su marca de tiempo
raise RuntimeError(data["error"] if data else "MetalAPI unreachable")Algunas costumbres más que mantienen una integración barata y fiable:
- Pide todos los símbolos en una sola llamada.
currencies=XAU,XAG,XPT,XPDcuesta una solicitud; cuatro llamadas separadas cuestan cuatro. - Mantén la clave en el servidor. Si un navegador tiene que llamar a la API, usa una clave restringida por dominio. Para mostrar precios en un sitio web sin escribir código, un widget integrable mantiene la clave completamente fuera de la página.
- Muestra la marca de tiempo.
timestampes la hora de los datos, no la de tu solicitud. Muéstrala junto al precio, sobre todo cuando sirves un valor en caché o el mercado está cerrado por el fin de semana. - Presupuesta tus consultas. Consultar cada 10 minutos consume unas 4500 solicitudes al mes, y consultar cada minuto, unas 45.000. Desde el plan Pro puedes usar el stream en tiempo real en su lugar, y desde Advanced puedes recibir alertas de precio por webhook.
- Usa tiempos de espera y reintentos selectivos. Establece un tiempo de espera de unos 10 segundos, reintenta
104después deRetry-Aftery los errores5xxcon espera exponencial, y nunca reintentes los errores de validación. - Valida los símbolos de antemano. Carga
/symbolsuna vez al arrancar (es gratuito) y rechaza los códigos desconocidos antes de que te cuesten una solicitud.
Si trabajas con asistentes de IA, el servidor MCP de MetalAPI en https://metalapi.com/mcp expone los mismos datos como herramientas, para que Claude, ChatGPT, Cursor o VS Code puedan consultar precios e historial del oro con tu plan; consulta IA y MCP. Para cada endpoint y parámetro, la referencia es la documentación de la API.
Pruébalo con tus propios datos
Crea una cuenta gratuita y haz tu primera solicitud en menos de dos minutos. 100 solicitudes al mes, sin tarjeta de crédito.
Sigue leyendo
Cómo añadir un widget del precio del oro en vivo a tu sitio web
Añade un widget del precio del oro en vivo a WordPress, Shopify o HTML: créalo en el panel de MetalAPI, elige símbolos, diseño y tema, y pega dos líneas de código.
Precios del oro por quilate: 24K, 22K, 18K y cómo calcularlos
Qué significan 24K, 22K y 18K, cómo se relacionan con leyes como 916 y 750, cómo calcular el precio por gramo del oro por quilate y cómo obtenerlo de una API.
Crea una calculadora de precios de joyería con el oro en tiempo real
Crea una calculadora de precios de joyería en el servidor con TypeScript y Python: oro por gramo en tiempo real, quilates, hechura, IVA y una caché que cuida tu cuota.