Rate limiting
Limites de uso de la API de Karrito por endpoint, headers de respuesta y buenas practicas.
Limites por endpoint
La API aplica rate limiting para garantizar estabilidad y un uso justo del servicio. Los limites varian segun el endpoint y el tipo de autenticacion.
Endpoints autenticados (API key)
| Endpoint | Limite | Ventana |
|---|---|---|
GET /api/v1/products |
100 requests | 1 minuto |
GET /api/v1/products/:id |
100 requests | 1 minuto |
GET /api/v1/categories |
100 requests | 1 minuto |
GET /api/v1/orders |
100 requests | 1 minuto |
GET /api/v1/orders/:id |
100 requests | 1 minuto |
El limite se comparte entre todos los endpoints autenticados. Si haces 60 requests a productos y 40 a categorias en el mismo minuto, llegas al limite.
Endpoints publicos (por IP)
| Endpoint | Limite | Ventana |
|---|---|---|
POST /api/orders |
10 requests | 1 minuto |
POST /api/reviews |
3 requests | 24 horas |
GET /api/check-slug |
30 requests | 1 hora |
Estos endpoints no requieren API key y se limitan por direccion IP del cliente.
Headers de respuesta
Cada respuesta de la API incluye headers que te informan del estado de tu cuota:
| Header | Descripcion | Ejemplo |
|---|---|---|
X-RateLimit-Limit |
Limite maximo de la ventana | 100 |
X-RateLimit-Remaining |
Requests restantes en esta ventana | 73 |
Retry-After |
Segundos hasta que se resetea la ventana (solo en 429) | 23 |
Ejemplo de headers
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73Cuando recibes 429
Si excedes el limite, la API responde con 429 Too Many Requests:
{
"error": "Demasiadas peticiones. Intenta de nuevo en 23 segundos.",
"code": "RATE_LIMIT_EXCEEDED"
}Los headers te dicen cuanto esperar:
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
Retry-After: 23Como manejar un 429
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") || "5");
console.log(`Rate limited. Esperando ${retryAfter}s...`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
continue;
}
return response;
}
throw new Error("Max retries alcanzado");
}Buenas practicas
Cachear respuestas
Si consultas los mismos datos repetidamente, guarda la respuesta en cache local. Los productos y categorias no cambian cada segundo.
// Cache simple en memoria (5 minutos)
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000;
async function getProducts() {
const cached = cache.get("products");
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return cached.data;
}
const response = await fetch("https://karrito.shop/api/v1/products", {
headers: { "Authorization": "Bearer " + API_KEY }
});
const result = await response.json();
cache.set("products", { data: result, timestamp: Date.now() });
return result;
}Paginar eficientemente
No pidas 100 productos si solo necesitas 10. Usa limit para traer solo lo que necesitas.
# Mal: traer todo
curl "https://karrito.shop/api/v1/products?limit=100"
# Bien: traer solo lo necesario
curl "https://karrito.shop/api/v1/products?limit=10"Monitorear tus headers
Revisa X-RateLimit-Remaining en cada respuesta. Si ves que baja rapido, ajusta la frecuencia de tus peticiones antes de llegar al limite.
Evitar loops sin control
Si sincronizas datos, agrega delays entre paginas:
async function syncAllProducts() {
let offset = 0;
const limit = 50;
while (true) {
const response = await fetch(
`https://karrito.shop/api/v1/products?limit=${limit}&offset=${offset}`,
{ headers: { "Authorization": "Bearer " + API_KEY } }
);
const { data, total } = await response.json();
// Procesar productos...
offset += limit;
if (offset >= total) break;
// Esperar 500ms entre paginas
await new Promise(resolve => setTimeout(resolve, 500));
}
}Siguiente paso
Consulta la referencia de errores para manejar correctamente las respuestas de error.