Saltar al contenido principal

Rate limits

Neuroon aplica rate limiting por endpoint, no por plan de subscripción. La cuota por plan (productos sincronizados, búsquedas mensuales) es un concepto separado del throttling de tasa que documenta esta página. Ver Cuotas de plan vs rate limit más abajo.

Hay dos capas de throttling: una sobre /api/plugin/shops/* (autenticada con Shop API Key) y otra sobre /api/widget/* (autenticada con Widget Token). Los límites son globales por endpoint — no varían según el plan.

Límites por endpoint

EndpointLímiteVentana
POST /api/plugin/shops/{shopId}/products/sync100 req1 min
GET /api/plugin/shops/me60 req1 min
GET /api/plugin/shops/{shopId}/verification-data20 req1 min
POST /api/plugin/shops/{shopId}/verify5 req5 min
DELETE /api/plugin/shops/{shopId}/verify5 req5 min
/api/widget/search*200 req1 min
/api/widget/suggestions*300 req1 min
/api/widget/compare*10 req1 min
/api/widget/analytics*500 req1 min
Resto de endpoints rate-limited100 req1 min

Headers de respuesta

HeaderCuándo se emiteSignificado
X-RateLimit-LimitToda respuesta rate-limited (200 y 429)Cuota total para este endpoint
X-RateLimit-RemainingToda respuesta rate-limitedRequests restantes en la ventana actual
Retry-AfterSólo en 429Segundos a esperar antes de reintentar (igual al tamaño de ventana)

Ejemplo de respuesta correcta:

HTTP/1.1 200 OK
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 187
Content-Type: application/json

Cuerpo del error 429

Cuando el bucket se agota, la respuesta es:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 0
Retry-After: 60
Content-Type: application/json

{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please try again later.",
"retryAfter": 60,
"limit": 200,
"remaining": 0,
"timestamp": "2026-05-06T10:15:00Z"
}

Backoff exponencial

Reintenta sólo en 429 y 5xx. Respeta Retry-After. Patrón recomendado: 1s, 2s, 4s, 8s con jitter, máximo 3-5 intentos.

using Polly;
using Polly.Extensions.Http;

var retryPolicy = HttpPolicyExtensions
  .HandleTransientHttpError()
  .OrResult(msg => (int)msg.StatusCode == 429)
  .WaitAndRetryAsync(
      retryCount: 3,
      sleepDurationProvider: (attempt, response, ctx) =>
      {
          if (response.Result?.Headers.RetryAfter?.Delta is TimeSpan retryAfter)
              return retryAfter;
          return TimeSpan.FromMilliseconds(
              Math.Pow(2, attempt) * 1000 + Random.Shared.Next(0, 250));
      },
      onRetryAsync: (_, _, _, _) => Task.CompletedTask);

var http = new HttpClient(new PolicyHttpMessageHandler(retryPolicy)
            { InnerHandler = new HttpClientHandler() });

Cuotas de plan vs rate limit

Son dos capas distintas. No las confundas:

ConceptoQué controlaDónde se veGranularidad
Rate limit (esta página)Picos por minuto/cinco minutosHeaders X-RateLimit-*, error 429Por endpoint, igual para todos
Cuota de planVolumen total mensual y catálogo máximoGET /api/plugin/shops/memaxProducts, productsCount, maxSearchesPerMonth, searchesThisMonthPor shop, depende del plan

El plan tier (BASIC, GROWTH, PRO, ENTERPRISE) afecta a maxProducts y maxSearchesPerMonth retornados por /shops/me, no a los rate limits por endpoint, que son globales. Si tu integración necesita más volumen mensual, contacta soporte para subir de plan; los rate limits por endpoint no se elevan por plan.

Buenas prácticas

  • Cachea /api/plugin/shops/me unos 5 min en el cliente como hace el plugin WordPress oficial; el endpoint sólo permite 60 req/min y productsCount/searchesThisMonth cambian lentamente.
  • No abuses de widget-compare (10/min): cachea resultados o agrupa comparaciones.
  • Sincroniza productos en lotes de hasta 500 (límite del endpoint sync) y espacia las llamadas; el bucket de sync permite 100 req/min, suficiente para catálogos grandes si paginan bien.
  • No reintentes en 400, 401, 403, 404 ni 422 — son errores deterministas, reintentar no los corrige.
  • Respeta Retry-After estrictamente. Ignorarlo puede llevar a abuso y bloqueo manual.

Próximas lecturas

  • Errores — estructura completa del resto de errores 4xx/5xx.
  • Shop API Key — generación, rotación y validación de Origin.
  • Widget Token — TTL 24 h y renovación.