Gestion des erreurs
Les codes d'erreur de MetalAPI, les statuts HTTP correspondants, et comment gérer les requêtes échouées et les relancer avec une stratégie adaptée.
Format des réponses d'erreur
Lorsqu'une requête échoue, l'API répond avec un statut HTTP d'erreur et un corps JSON contenant success: false. L'objet error contient un code numérique, un type lisible par une machine et un message info lisible par un humain :
{
"success": false,
"error": {
"code": 101,
"type": "no_api_key",
"info": "User did not supply an API Key"
}
}Basez votre logique sur code ou type, pas sur le texte de info, qui peut changer. Les codes sont les mêmes que dans les versions précédentes de MetalAPI : les intégrations existantes continuent donc de fonctionner.
Erreurs d'authentification et de compte
101no_api_key(401) : la requête ne contient pas de clé API.102invalid_api_key(401) : la clé est inconnue ou a été révoquée.103account_inactive(403) : le compte n'est pas actif. Contactez le support.107origin_not_allowed(403) : une clé restreinte par domaine a été utilisée depuis un site web qui ne figure pas dans sa liste de domaines autorisés.
Erreurs de limite et de plan
104too_many_requests(429) : la limite par minute a été atteinte. Attendez le nombre de secondes indiqué dans l'en-têteRetry-After.105quota_exceeded(429) : le quota mensuel est épuisé jusqu'au 1er du mois suivant (UTC).106plan_restriction(403) : l'endpoint ou le paramètre n'est pas inclus dans votre plan, par exemple/caratsur Free ouXAU-BIDen dessous de Standard.
Erreurs de validation
Ces erreurs renvoient le statut HTTP 400 et signifient que la requête elle-même doit être corrigée :
201invalid_base: symbolebaseinconnu.202invalid_fromet203invalid_to: symbolefromoutoinconnu dans/convert.204invalid_amount:amountest absent ou n'est pas un nombre.205invalid_date: date mal formée, ou date située dans le futur.206invalid_timeframe:start_dateouend_dateest absent, ou la date de début est postérieure à la date de fin.207timeframe_too_long: la plage dépasse ce que votre plan autorise (30 jours sur Free, 365 sur les plans payants).208invalid_symbols: aucun des symboles demandés n'existe.209invalid_unit:unitnon prise en charge.210invalid_carat: carat non pris en charge.
Dans currencies, les symboles inconnus sont ignorés tant qu'au moins un symbole est valide.
Autres erreurs
300no_results(404) : la requête est valide mais aucune donnée n'existe, par exemple pour une date antérieure au début de l'historique d'un symbole.404invalid_function(404) : endpoint inconnu. Vérifiez l'URL.500server_error(500) : une erreur inattendue de notre côté.503service_unavailable(503) : les données de prix sont temporairement indisponibles.
Gérer les erreurs dans votre code
Vérifiez success sur chaque réponse et transformez les échecs en erreurs que votre code peut examiner. Ce helper gère aussi les réponses non JSON renvoyées par des proxys :
async function metalapi(path, params = {}) {
const url = new URL(`https://metalapi.com/api/v1/${path}`);
for (const [key, value] of Object.entries(params)) url.searchParams.set(key, value);
const res = await fetch(url, { headers: { "X-API-Key": process.env.METALAPI_KEY } });
const data = await res.json().catch(() => ({
success: false,
error: { code: res.status, type: "http_error", info: res.statusText },
}));
if (!data.success) {
const err = new Error(`MetalAPI ${data.error.code} (${data.error.type}): ${data.error.info}`);
err.code = data.error.code;
err.retryAfter = Number(res.headers.get("Retry-After")) || undefined;
throw err;
}
return data;
}Stratégie de nouvelles tentatives
Ne relancez que les erreurs susceptibles de réussir à la tentative suivante :
104: attendezRetry-Aftersecondes, puis réessayez.500,503et erreurs réseau : réessayez avec un backoff exponentiel (1 s, 2 s, 4 s) et abandonnez après trois nouvelles tentatives.- Tout le reste (
101à103,105à107, les codes de validation2xx,300,404) : ne réessayez pas. Corrigez plutôt la requête, la clé ou le plan.
Relancer les erreurs 104 et 5xx ne coûte rien, car ces requêtes échouées ne sont pas facturées.
async function withRetry(fn, retries = 3) {
for (let attempt = 0; ; attempt++) {
try {
return await fn();
} catch (err) {
const retryable = err.code === undefined || err.code === 104 || err.code >= 500;
if (!retryable || attempt >= retries) throw err;
const delay = err.retryAfter ? err.retryAfter * 1000 : 1000 * 2 ** attempt;
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
const data = await withRetry(() => metalapi("latest", { currencies: "XAU,XAG" }));Guides associés
Prêt à commencer ?
Créez un compte gratuit pour obtenir votre clé API, ou explorez tous les endpoints dans la référence de l'API.