Facturiadocs
Autenticación

Límites de tasa

Los buckets publicados, los headers que te dicen dónde estás, y las dos realidades del SII para las que igual conviene diseñar.

Los headers

Cada respuesta autenticada lleva:

RateLimit-Limit: 300
RateLimit-Remaining: 287
RateLimit-Reset: 41

Reportan el bucket más ajustado que aplica, no el general: un request que está a una emisión de agotar su cuota por segundo lo dice, aunque le queden 280 requests generales.

En un 429, el header Retry-After (en segundos) te dice exactamente cuánto esperar. No adivines con backoff exponencial cuando la respuesta trae la cifra.

Los endpoints sin autenticación no se cuentan y no llevan estos headers: GET /v1/error_codes sirve una constante sin datos de nadie.

Los buckets publicados

Por defecto, por credencial — una llave o una sesión de cuenta, cada modo por separado:

BucketLímiteVentanaSe cuenta por
API general300 req/minminuto deslizantecredencial
POST /v1/documents10 req/ssegundo deslizantecredencial
POST /v1/tax/f29/filings10 req/minminuto deslizantecredencial + empresa
POST /v1/tax/sync10 req/minminuto deslizantecredencial + empresa
POST /v1/documents/{document_id}/send20 req/minminuto deslizantecredencial
Descarga de artefactos (PDF, XML, recibidos)60 req/minminuto deslizantecredencial
https://ver.facturia.cl/d/{slug}60 req/minminuto deslizanteel enlace

Lo que importa más que los números:

  • Declaración y sincronización se cuentan aparte. Comparten el límite, no el contador: uno solo dejaría que una ráfaga de sincronizaciones se gastara la cuota que la declaración necesita el 20.
  • El envío por correo tiene bucket propio porque recibe una lista de direcciones del cliente y adjunta un PDF — la forma exacta de un cañón de correo. 20/min es generoso para facturar e inservible para cualquier otra cosa.
  • Los enlaces públicos se cuentan por slug, no por quien llama. /d/{slug} es la única ruta sin credencial, así que el enlace es lo único estable que contar. No hay conteo por IP.
  • No hay ráfaga. Una versión anterior de esta tabla traía una columna "Ráfaga" que contradecía su propio texto; el limitador aplica las ventanas deslizantes de arriba y nada más. Dimensiona tus reintentos al límite, no a una ráfaga.

Estos son límites de partida, y se suben cuando lo pides: cuéntanos tu volumen y ajustamos. No necesitas cambiar de plan para tener más throughput. Los publicamos para que puedas dimensionar reintentos y backoff, no como una promesa competitiva.

El modo test aplica los mismos límites que live, así que una prueba de carga es representativa.

Cómo se comporta un 429

Un 429 es del tipo rate_limit_error. La emisión está encolada de nuestro lado: una ráfaga sobre 10 req/s es un 429 del lado del cliente, nunca un documento perdido. Reintenta con el Retry-After que te devolvimos y el documento sale.

async function emitir(payload, idempotencyKey) {
  for (let intento = 0; intento < 5; intento += 1) {
    const res = await fetch('https://api.facturia.cl/v1/documents', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.FACTURIA_KEY}`,
        'Facturia-Empresa': process.env.EMPRESA,
        'Idempotency-Key': idempotencyKey, // el mismo en cada reintento
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(payload),
    });

    if (res.status !== 429) return res;

    const esperar = Number(res.headers.get('Retry-After') ?? 1);
    await new Promise((r) => setTimeout(r, esperar * 1000));
  }
  throw new Error('rate limit persistente');
}

Reutilizar el mismo Idempotency-Key en cada reintento es lo que garantiza que cinco intentos produzcan un documento y no cinco.

Cuota de plan, que no es lo mismo

402 plan_limit_reached aparece cuando se agota una cuota del plan; el cuerpo nombra el límite y la URL para subir de plan. El modo test nunca tiene límite por plan.

Un 429 dice «más lento». Un 402 dice «ya no». Son problemas distintos con soluciones distintas.

Las dos realidades de arriba

Por encima de nuestros límites hay dos realidades del SII para las que conviene diseñar:

  1. El SII limita tasa y no publica sus cifras.
  2. El SII tiene ventanas de mantención programadas.

Ninguna de las dos te va a perder un documento — la emisión está encolada — pero un documento que ya aceptamos va a quedarse en queued más tiempo durante una caída del SII. Por eso status.facturia.cl publica el estado de nuestros componentes y el del SII: la mitad de los incidentes de esta categoría son del SII, y mereces saber en cuál mitad estás.

Construye sobre webhooks

Un integrador que hace polling apretado durante una caída del SII se auto-limita justo cuando menos información hay. Un integrador que escucha document.accepted no nota la diferencia salvo por la latencia. La página de Webhooks tiene el catálogo completo.

En esta página