Tratamento de Erros

A API retorna respostas padronizadas para facilitar o tratamento de erros. Todos os erros incluem um código único e mensagem descritiva.

Formato da Resposta de Erro

JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "O campo 'email' é obrigatório",
    "details": {
      "field": "email",
      "reason": "required"
    }
  }
}

Códigos HTTP

2xx - Sucesso

A requisição foi processada com sucesso.

  • 200 - OK (GET, PATCH)
  • 201 - Created (POST)
  • 204 - No Content (DELETE)

4xx - Erro do Cliente

Há um problema com a requisição enviada.

  • 400 - Bad Request (dados inválidos)
  • 401 - Unauthorized (API Key inválida)
  • 403 - Forbidden (sem permissão)
  • 404 - Not Found (recurso não existe)
  • 409 - Conflict (recurso já existe)
  • 422 - Unprocessable Entity (validação falhou)
  • 429 - Too Many Requests (rate limit)

5xx - Erro do Servidor

Erro interno no servidor. Tente novamente.

  • 500 - Internal Server Error
  • 502 - Bad Gateway
  • 503 - Service Unavailable

Códigos de Erro Comuns

HTTPCodigoDescricaoAcao
400VALIDATION_ERRORDados inválidos no bodyVerifique os campos enviados
400INVALID_JSONJSON malformadoVerifique a sintaxe do JSON
401UNAUTHORIZEDAPI Key não fornecida ou inválidaVerifique o header Authorization
401API_KEY_EXPIREDAPI Key expiradaCrie uma nova API Key
403FORBIDDENSem permissão para esta operaçãoVerifique os escopos da API Key
403SCOPE_REQUIREDEscopo específico necessárioAdicione o escopo à API Key
404NOT_FOUNDRecurso não encontradoVerifique o ID/externalId
409CONFLICTRecurso já existeUse update ou outro externalId
409DUPLICATE_ENTRYEntrada duplicadaO registro já existe
422UNPROCESSABLE_ENTITYEntidade não processávelDados válidos mas não podem ser processados
429RATE_LIMIT_EXCEEDEDLimite de requisições excedidoAguarde o tempo indicado em Retry-After
500INTERNAL_ERRORErro interno do servidorTente novamente ou contate suporte

Erros de Validação

Quando há erros de validação (400/422), o campo detailscontém informações específicas sobre cada campo:

JSON
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "errors": [
        {
          "field": "email",
          "message": "Email inválido",
          "code": "invalid_email"
        },
        {
          "field": "phone",
          "message": "Formato de telefone inválido",
          "code": "invalid_format"
        }
      ]
    }
  }
}

Estratégia de Retry

Recomendamos implementar retry com backoff exponencial para erros recuperáveis:

CódigoRetry?Ação
400❌ NãoCorrija os dados e reenvie
401❌ NãoVerifique a API Key
403❌ NãoVerifique permissões
404❌ NãoVerifique o ID
429✅ SimAguarde Retry-After
500✅ SimRetry com backoff
502/503✅ SimRetry com backoff

Exemplo de Implementação

JavaScript
async function apiRequest(url, options, maxRetries = 3) {
  let lastError;
  
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      // Sucesso
      if (response.ok) {
        return await response.json();
      }
      
      // Erro não recuperável
      if ([400, 401, 403, 404].includes(response.status)) {
        const error = await response.json();
        throw new Error(error.error?.message || 'Request failed');
      }
      
      // Rate limit - aguarda tempo indicado
      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        await sleep(retryAfter * 1000);
        continue;
      }
      
      // Erro do servidor - retry com backoff
      if (response.status >= 500) {
        const delay = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
        await sleep(delay);
        continue;
      }
      
    } catch (error) {
      lastError = error;
      
      // Erro de rede - retry
      if (error.name === 'TypeError') {
        const delay = Math.pow(2, attempt) * 1000;
        await sleep(delay);
        continue;
      }
      
      throw error;
    }
  }
  
  throw lastError || new Error('Max retries exceeded');
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}