Límites de peticiones
Cuotas por minuto y mensuales según el tier. Cabeceras X-RateLimit-* y back-off recomendado.
La API pública aplica dos niveles de cuota para garantizar la equidad entre tenants y proteger el backend frente a picos:
- Cuota por minuto (ventana deslizante).
- Cuota mensual (calendario natural, se reinicia el día 1 a las 00:00 Europe/Madrid).
Los límites dependen del tier de tu API key. El tier por defecto al crear
una clave se controla desde Developers > API Keys > Settings > Default tier, y puede sobrescribirse por clave desde el dashboard.
Niveles
| Tier | Por minuto | Por mes | Coste |
|---|---|---|---|
| Free | 10 rpm | 100 requests | Incluido en cualquier plan. |
| Starter | 30 rpm | 5,000 | Add-on developer_api Starter (€4.90/mes). |
| Pro | 300 rpm | 50,000 | Add-on developer_api Pro (€19.90/mes). |
| Scale | Personalizado | Personalizado | Contacta con ventas. |
Los tiers son acumulativos: una vez agotada la cuota mensual recibes
429 rate_limit_exceeded hasta el día 1 del mes siguiente. La cuota por
minuto se reinicia con una ventana deslizante.
Ventana deslizante
El cubo por minuto no es una ventana fija de "60 segundos desde las 12:00".
Es una ventana deslizante: en cualquier momento, la API cuenta cuántas
peticiones aceptadas hay en los últimos 60 segundos para tu clave. Cuando el
contador iguala al límite, las peticiones siguientes responden 429 hasta
que pase suficiente tiempo para que las primeras peticiones "salgan" de la ventana.
Por qué: no hay un "minuto de gracia" cada 60 segundos en el que pudieras enviar el doble del límite. Más justo y más estable bajo tráfico real.
Cabeceras de respuesta
Toda respuesta (incluido 429) incluye:
| Cabecera | Significado |
|---|---|
X-RateLimit-Limit | Límite por minuto de tu tier. |
X-RateLimit-Remaining | Peticiones restantes en la ventana actual. |
X-RateLimit-Reset | Timestamp UNIX en el que se libera un hueco (una petición sale de la ventana). |
Retry-After | Solo en 429. Segundos hasta que puedas reintentar. |
Ejemplo de cabeceras en una respuesta 200:
HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1747314060Y en un 429:
HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1747314007Código de error
{
"error": {
"type": "rate_limit_error",
"code": "rate_limit_exceeded",
"message": "Has superado el límite de peticiones. Vuelve a intentarlo en unos segundos.",
"request_id": "req_..."
}
}Superar la cuota por minuto o la mensual responde 429 con
type: rate_limit_error y code: rate_limit_exceeded. La cabecera
Retry-After (y el mensaje) te indican cuánto debes esperar.
Los fallos de autenticación repetidos se limitan por separado con
code: too_many_auth_failures.
Buenas prácticas
1. Respeta Retry-After
import time, requests
def call_with_retry(url, **kwargs):
while True:
resp = requests.get(url, **kwargs)
if resp.status_code != 429:
return resp
sleep = int(resp.headers.get('Retry-After', 1))
time.sleep(sleep)2. Back-off exponencial con jitter
Para 5xx, donde no hay Retry-After:
import random, time
def backoff(attempt):
return min(60, (2 ** attempt) * 0.1 + random.uniform(0, 0.5))
for attempt in range(5):
resp = requests.get(url)
if resp.status_code < 500:
break
time.sleep(backoff(attempt))3. Monitoriza X-RateLimit-Remaining
Si tu integración se acerca de forma consistente al 10% del límite, considera:
- Subir de tier.
- Agrupar en lotes: en lugar de N POSTs, agrega y haz 1 POST.
- Cachear lecturas frecuentes (productos, impuestos, series).
- Suscribirte a webhooks en lugar de hacer polling.
4. Webhooks > polling
Si haces polling de /v1/invoices?status=paid cada minuto para detectar pagos
consumes 30 rpm solo para eso. Suscríbete al evento invoice.paid
y reduce eso a 0 peticiones.
5. Tier por integración
Si tienes dos integraciones (un dashboard interno + un cron de exportación), crea dos claves distintas con tiers dimensionados para cada una. Así un cron pesado no agota el presupuesto de un dashboard interactivo.
Cuotas administrativas
Algunos endpoints tienen cuotas adicionales independientes del rate limit principal:
| Endpoint | Cuota |
|---|---|
POST /v1/webhook_endpoints | Número limitado de endpoints por empresa. |
POST /v1/invoices/{id}/send | Limitado por factura para evitar emails duplicados. |
GET /v1/invoices/{id}/pdf | Generaciones de PDF limitadas por minuto. |
Estos límites responden 429 con type: rate_limit_error y un mensaje
específico.
Subida de tier
Cambiar de tier no requiere rotar claves. Tras suscribirte a un add-on superior:
- Las nuevas cuotas aplican de inmediato.
- La cuota mensual consumida en el tier anterior no se reinicia: solo crece el tope mensual.
- Las claves existentes conservan su
idy su tier; gestiona los tiers desde el dashboard (Developers > API Keys).
Errores
Envoltorio de error normalizado, catálogo de type y code con anclas estables, y estrategia de reintentos.
Importes y fechas
Cómo representa la API el dinero (EUR, dos decimales), las fechas (YYYY-MM-DD), los timestamps (ISO-8601) y la zona horaria Europe/Madrid usada para el reinicio de cuotas.