Tratamento de erros
Códigos de erro da MetalAPI, seus status HTTP correspondentes e como tratar requisições com falha e repeti-las com uma estratégia de novas tentativas.
Formato da resposta de erro
Quando uma requisição falha, a API responde com um status HTTP de erro e um corpo JSON com success: false. O objeto error contém um code numérico, um type legível por máquina e uma mensagem info legível por humanos:
{
"success": false,
"error": {
"code": 101,
"type": "no_api_key",
"info": "User did not supply an API Key"
}
}Baseie a sua lógica em code ou type, e não no texto de info, que pode mudar. Os códigos são os mesmos das versões anteriores da MetalAPI, então as integrações existentes continuam funcionando.
Erros de autenticação e de conta
101no_api_key(401): a requisição não tem chave de API.102invalid_api_key(401): a chave é desconhecida ou foi revogada.103account_inactive(403): a conta não está ativa. Entre em contato com o suporte.107origin_not_allowed(403): uma chave restrita por domínio foi usada a partir de um site que não está na sua lista de domínios permitidos.
Erros de limite e de plano
104too_many_requests(429): o limite por minuto foi atingido. Aguarde o número de segundos indicado no cabeçalhoRetry-After.105quota_exceeded(429): a cota mensal está esgotada até o dia 1º do próximo mês (UTC).106plan_restriction(403): o endpoint ou parâmetro não está incluído no seu plano, como/caratno Free ouXAU-BIDabaixo do Standard.
Erros de validação
Estes retornam o status HTTP 400 e significam que a própria requisição precisa ser corrigida:
201invalid_base: símbolobasedesconhecido.202invalid_frome203invalid_to: símbolofromoutodesconhecido em/convert.204invalid_amount:amountestá ausente ou não é um número.205invalid_date: data malformada ou no futuro.206invalid_timeframe:start_dateouend_dateestá ausente, ou o início é posterior ao fim.207timeframe_too_long: o intervalo é maior do que o seu plano permite (30 dias no Free, 365 nos planos pagos).208invalid_symbols: nenhum dos símbolos solicitados existe.209invalid_unit:unitnão suportada.210invalid_carat: quilate não suportado.
Em currencies, símbolos desconhecidos são ignorados desde que pelo menos um símbolo seja válido.
Outros erros
300no_results(404): a consulta é válida, mas não há dados, por exemplo para uma data anterior ao início do histórico de um símbolo.404invalid_function(404): endpoint desconhecido. Verifique a URL.500server_error(500): um erro inesperado do nosso lado.503service_unavailable(503): os dados de preços estão temporariamente indisponíveis.
Tratando erros no código
Verifique success em toda resposta e transforme as falhas em erros que o seu código possa inspecionar. Este helper também lida com respostas não JSON vindas de proxies:
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;
}Estratégia de novas tentativas
Só repita os erros que podem ter sucesso em uma segunda tentativa:
104: aguardeRetry-Aftersegundos e tente novamente.500,503e erros de rede: tente novamente com backoff exponencial (1 s, 2 s, 4 s) e desista após três novas tentativas.- Todo o resto (
101a103,105a107, os códigos de validação2xx,300,404): não repita. Em vez disso, corrija a requisição, a chave ou o plano.
Repetir erros 104 e 5xx não custa nada, porque essas requisições com falha não são cobradas.
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" }));Guias relacionados
Pronto para começar a desenvolver?
Crie uma conta grátis para obter sua chave de API ou explore todos os endpoints na referência da API.