Saltar al contenido principal

Rate limits

Política de control de tasa de uso de la API pública y del relay SMTP.

Estado actual

Tipo de límiteEstadoDonde se enforce
Requests/segundo por API keyPlaneado
Requests/segundo por tenant (agregado)Planeado
Mensajes/segundo SMTP por credencialPlaneado

Para bandwidth shaping (activo):

  • El cap se mide en bytes-on-wire estimados: len(EML) × num_recipients por send.
  • HTTP: cuando se excede, la API responde 429 Too Many Requests con header Retry-After (segundos). Un único request que supere la capacity total del burst devuelve 413 Payload Too Large permanente.
  • SMTP: cuando se excede, el relay responde 452 4.3.1 Instance bandwidth limit exceeded, retry in <seg>s en END-OF-MESSAGE. La MTA emisora reintentará con su propia política de backoff.
  • El cap por instance y su burst_seconds se configuran a nivel infra (no son negociables por contrato hoy). Subida del límite por necesidad operativa o comercial: contactar soporte.

Los otros límites (req/s por API key, etc.) siguen siendo planeados, no implementados. Los integradores deben diseñar clientes asumiendo que van a existir (ver valores y headers abajo).

Scope diseñado

Los límites se aplican en dos planos:

  1. API pública (envío y consultas):

    • Por API key: requests/segundo individualmente por credencial.
    • Por tenant: suma agregada de todas las API keys del tenant.
    • Por endpoint: límites específicos en endpoints caros (exports, búsquedas amplias).
  2. SMTP relay (API pública → relay SMTP):

    • Por credencial SMTP: mensajes/segundo enviables vía SASL PLAIN.
    • Por tenant: agregado SMTP.

Los valores por defecto y por plan se acuerdan con comercial. Referencia tentativa:

PlanRequests API/sEnvíos SMTP/s
Starter1020
Standard50100
EnterpriseCustomCustom

Headers y respuesta 429

Cuando el rate limit esté implementado, las respuestas HTTP incluirán:

HeaderSignificado
X-RateLimit-LimitCupo total en la ventana actual
X-RateLimit-RemainingRequests restantes en la ventana
X-RateLimit-ResetTimestamp Unix cuando se resetea la ventana
Retry-AfterSegundos hasta el próximo request permitido (solo en 429)

Respuesta al exceder el límite — mismo envelope RFC 9457 application/problem+json que usan las tres APIs para todo error (ver Respuestas de error):

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1713531000
Retry-After: 12
Content-Type: application/problem+json

{
"type": "https://docs.fidelizador.com/errors/rate-limit-exceeded",
"title": "Too Many Requests",
"status": 429,
"detail": "API rate limit exceeded. Retry after 12s.",
"code": "rate_limit_exceeded",
"trace_id": "019c9633-1d8f-7624-8394-17db17f86867"
}

El trace_id en el body permite correlacionar con logs en caso de soporte. El X-Request-Id de la respuesta (nunca en el body — ver) también sirve para correlación por request individual.

Estrategias de backoff recomendadas

Para el cliente que consume la API:

  1. Exponential backoff con jitter: empezar con el Retry-After recibido; si vuelve a fallar, duplicar con jitter aleatorio (±20%) para evitar thundering herd.
  2. Circuit breaker: si más del 50% de las últimas 20 requests son 429, pausar todo el envío por ~30s.
  3. Bucket preventivo: mantener un token bucket local del lado del cliente usando X-RateLimit-Remaining para evitar alcanzar el límite en primer lugar.
  4. Distribución temporal: para campañas masivas, espaciar el envío en ventanas (ejemplo: 1000 correos/minuto en vez de 60000 de golpe).

Cómo se implementará

Diseño técnico (planeado, sujeto a cambio):

  • Contadores en memoria compartida: ventanas deslizantes de conteo con expiración automática.
  • Enforcement en la API pública: middleware que consulta el contador antes de procesar la ruta. Ante 429, short-circuit sin tocar la base de datos.
  • Enforcement SMTP: en el relay antes de DATA, con un código transitorio + mensaje de retry. Esto es rate-limiting (frecuencia), distinto de la cuota mensual de envío - esa ya está activa y usa sus propios códigos (452 4.7.1 por sobrepaso, 550 5.7.1 sin suscripción activa, 451 4.3.0 si la fuente no responde): ver.
  • Configuración: por credencial y a nivel tenant.

Seguimiento de la implementación: issue interno (por crear).