Factuarea API
Conceptos clave

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:

  1. Cuota por minuto (ventana deslizante).
  2. 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

TierPor minutoPor mesCoste
Free10 rpm100 requestsIncluido en cualquier plan.
Starter30 rpm5,000Add-on developer_api Starter (€4.90/mes).
Pro300 rpm50,000Add-on developer_api Pro (€19.90/mes).
ScalePersonalizadoPersonalizadoContacta 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:

CabeceraSignificado
X-RateLimit-LimitLímite por minuto de tu tier.
X-RateLimit-RemainingPeticiones restantes en la ventana actual.
X-RateLimit-ResetTimestamp UNIX en el que se libera un hueco (una petición sale de la ventana).
Retry-AfterSolo 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: 1747314060

Y en un 429:

HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1747314007

Có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:

EndpointCuota
POST /v1/webhook_endpointsNúmero limitado de endpoints por empresa.
POST /v1/invoices/{id}/sendLimitado por factura para evitar emails duplicados.
GET /v1/invoices/{id}/pdfGeneraciones 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:

  1. Las nuevas cuotas aplican de inmediato.
  2. La cuota mensual consumida en el tier anterior no se reinicia: solo crece el tope mensual.
  3. Las claves existentes conservan su id y su tier; gestiona los tiers desde el dashboard (Developers > API Keys).

En esta página