Errores

Referencia de codigos de error HTTP, formato de respuestas de error y tips de debugging.

5 min de lecturaapi, errores, http, debuggingActualizado: 18 de marzo de 2026

Formato de error

Todas las respuestas de error siguen el mismo formato JSON:

{
  "error": "Descripcion legible del error",
  "code": "ERROR_CODE",
  "details": {}
}
Campo Tipo Siempre presente Descripcion
error string Si Mensaje legible que explica el problema
code string No Codigo de error para manejar programaticamente
details object No Informacion adicional (ej: campos invalidos)

Codigos HTTP

400 Bad Request

Los datos enviados son invalidos o estan incompletos.

{
  "error": "El campo 'name' es requerido",
  "code": "VALIDATION_ERROR",
  "details": {
    "field": "name",
    "reason": "required"
  }
}

Causas comunes:

  • Falta un campo requerido en el body
  • Un campo tiene el tipo incorrecto (string en lugar de number)
  • Un valor esta fuera del rango permitido (limit > 100)
  • El JSON del body esta mal formado

401 Unauthorized

La peticion no incluye autenticacion o las credenciales son invalidas.

{
  "error": "API key invalida o expirada",
  "code": "UNAUTHORIZED"
}

Causas comunes:

  • No incluiste el header Authorization
  • El formato del header es incorrecto (falta Bearer)
  • La API key fue eliminada o revocada
  • Typo en la API key

403 Forbidden

La autenticacion es valida pero no tienes permisos para este recurso.

{
  "error": "Tu API key no tiene el scope 'orders:read'",
  "code": "FORBIDDEN"
}

Causas comunes:

  • Tu API key no tiene el scope necesario para este endpoint
  • Estas intentando acceder a datos de otra tienda
  • Tu plan no incluye acceso a la API (disponible en Pro y Lifetime)

404 Not Found

El recurso solicitado no existe.

{
  "error": "Producto no encontrado",
  "code": "NOT_FOUND"
}

Causas comunes:

  • El ID del recurso es incorrecto o tiene un typo
  • El recurso fue eliminado
  • La URL del endpoint es incorrecta

409 Conflict

La operacion genera un conflicto con el estado actual.

{
  "error": "Orden duplicada detectada. Intenta de nuevo en unos minutos.",
  "code": "DUPLICATE_ORDER"
}

Causas comunes:

  • Intentar crear una orden duplicada dentro de la ventana de 5 minutos
  • Slug duplicado al crear un producto

429 Too Many Requests

Excediste el limite de peticiones permitidas.

{
  "error": "Demasiadas peticiones. Intenta de nuevo en 23 segundos.",
  "code": "RATE_LIMIT_EXCEEDED"
}

Revisa la seccion de rate limiting para detalles de limites por endpoint.

500 Internal Server Error

Error inesperado en el servidor. No es tu culpa.

{
  "error": "Error interno del servidor",
  "code": "INTERNAL_ERROR"
}

Si recibes un 500:

  • Reintenta la peticion despues de unos segundos
  • Si persiste, contacta soporte con la URL, el body, y la hora del error
  • No cambies nada de tu lado — el problema esta en nuestros servidores

Manejo de errores en JavaScript

Patron basico con try/catch

async function getProduct(id) {
  try {
    const response = await fetch(`https://karrito.shop/api/v1/products/${id}`, {
      headers: {
        "Authorization": "Bearer " + API_KEY
      }
    });

    if (!response.ok) {
      const error = await response.json();

      switch (response.status) {
        case 401:
          throw new Error("API key invalida. Verifica tu configuracion.");
        case 403:
          throw new Error("Sin permisos. Verifica los scopes de tu API key.");
        case 404:
          throw new Error(`Producto ${id} no encontrado.`);
        case 429:
          const retryAfter = response.headers.get("Retry-After");
          throw new Error(`Rate limited. Reintentar en ${retryAfter}s.`);
        default:
          throw new Error(error.error || "Error desconocido");
      }
    }

    const { data } = await response.json();
    return data;
  } catch (err) {
    console.error("Error al obtener producto:", err.message);
    throw err;
  }
}

Patron con reintentos

async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);

      // No reintentar errores del cliente (4xx) excepto 429
      if (response.status >= 400 && response.status < 500 && response.status !== 429) {
        const error = await response.json();
        throw new Error(`${response.status}: ${error.error}`);
      }

      // Reintentar 429 y 5xx
      if (response.status === 429 || response.status >= 500) {
        const retryAfter = parseInt(response.headers.get("Retry-After") || "5");
        const delay = response.status === 429
          ? retryAfter * 1000
          : Math.min(1000 * Math.pow(2, attempt), 30000);

        console.log(`Intento ${attempt}/${maxRetries}. Esperando ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }

      return response;
    } catch (err) {
      if (attempt === maxRetries) throw err;
    }
  }
}

Tips de debugging

Verifica tu API key

# Peticion de prueba rapida
curl -v "https://karrito.shop/api/v1/products?limit=1" \
  -H "Authorization: Bearer krt_live_a1b2c3d4e5f6g7h8i9j0"

El flag -v muestra los headers de respuesta, incluyendo rate limiting y errores detallados.

Revisa el body de tu peticion

# Validar que el JSON es correcto antes de enviar
echo '{"storeId": "abc", "items": []}' | python3 -m json.tool

Errores comunes

Sintoma Causa probable Solucion
Siempre 401 Header Authorization mal formado Verifica que sea Bearer TU_KEY (con espacio)
400 en POST Body no es JSON valido Verifica Content-Type: application/json y el formato del body
404 en todo Base URL incorrecta Usa https://karrito.shop/api/v1/ (con el /v1/)
403 inesperado Scope faltante Crea una nueva API key con los scopes necesarios
Timeouts Peticiones muy frecuentes Agrega delays entre peticiones, cachea respuestas