Límits de peticions
Quotes per clau, empresa i cartera gestionada segons el tier. Capçaleres X-RateLimit-* i back-off recomanat.
L'API pública avalua tres eixos de quota per garantir l'equitat entre tenants i protegir el backend davant de pics:
- API key — finestra lliscant per minut i volum mensual.
- Empresa — l'agregat de totes les claus de l'empresa.
- Cartera gestionada — l'empresa gestora i totes les filles actives, només quan la credencial pertany a una cartera.
Els límits depenen del tier de la teva API key. El tier es deriva del pla
de Factuarea de la teva empresa: mai no es fixa per clau ni per petició, no
existeix una compra de capacitat independent i s'actualitza automàticament
quan canvia el pla. Només les migracions històriques grandfathered_addon
poden conservar un tier superior, i únicament mentre l'empresa mantingui un
pla actiu vàlid.
Nivells
| Tier | Clau/min | Clau/mes | Empresa/min | Empresa/mes | Inclòs amb |
|---|---|---|---|---|---|
| Free | 10 | 100 | 10 | 100 | El trial de 10 dies. |
| Starter | 30 | 5.000 | 90 | 15.000 | El pla Emprendedor. |
| Pro | 300 | 50.000 | 900 | 150.000 | El pla Empresario. |
| Scale | 1.200 | 5.000.000 | 3.600 | 15.000.000 | El pla Enterprise. |
Els límits per clau s'apliquen. Els agregats per empresa són presents al
contracte i, a la versió entrant de l'aplicació, funcionen en mode
d'observació (shadow): mesuren els rebutjos que haurien ocorregut sense
retornar 429. No tractis aquest mode com a capacitat contractada; es pot
promocionar a aplicació efectiva després de calibrar-lo sense canviar la forma
de la petició ni de la resposta.
Les claus fact_test_ continuen consumint la quota per clau, però els eixos
agregats d'empresa i cartera ometen les empreses sandbox perquè el trànsit de
prova no consumeixi capacitat agregada de producció.
Finestra lliscant
El cub per minut no és una finestra fixa de "60 segons des de les 12:00".
És una finestra lliscant: en qualsevol moment, l'API compta quantes
peticions acceptades hi ha en els darrers 60 segons per a la teva clau. Quan el
comptador iguala el límit, les peticions següents responen 429 fins que
passa prou temps perquè les primeres peticions "surtin" de la finestra.
Per què: no hi ha cap "minut de gràcia" cada 60 segons en què poguessis enviar el doble del límit. Més just i més estable sota trànsit real.
Sostres d'empresa i cartera
Quan els eixos agregats estan en aplicació efectiva, l'API avalua primer la
clau, després l'empresa i finalment la cartera gestionada. Un rebuig d'empresa
fa servir company_rate_limit_exceeded o
company_monthly_quota_exceeded: afegir claus no eleva aquests sostres perquè
es compten totes juntes.
Una cartera gestionada té un catàleg pla independent per tier:
| Tier | Banda comuna/min | Sòl reservat per empresa activa/min | Cartera/mes | Claus actives a la cartera |
|---|---|---|---|---|
| Free | 10 | 10 | 100 | 1 |
| Starter | 180 | 20 | 150.000 | 15 |
| Pro | 1.800 | 30 | 1.500.000 | 500 |
| Scale | 7.200 | 60 | 50.000.000 | 2.000 |
El sòl reservat per empresa s'avalua primer. Una filla per sota del seu sòl pot
continuar encara que la banda comuna s'hagi exhaurit; la banda comuna no és,
per tant, un total absolut de la cartera. La quota mensual no té sòl i agrega
tota la cartera. Aquests valors també estan actualment en mode shadow,
pendents de calibració amb trànsit real de tancament.
Els rebutjos de cartera fan servir portfolio_rate_limit_exceeded i
portfolio_monthly_quota_exceeded. Crear més empreses filles o API keys no
eleva un sostre pla de cartera; reparteix la feina en el temps o sol·licita una
ampliació auditada per a l'empresa.
Capçaleres de resposta
Tota resposta (inclòs 429) inclou:
| Capçalera | Significat |
|---|---|
X-RateLimit-Limit | Límit per minut del teu tier. |
X-RateLimit-Remaining | Peticions restants a la finestra actual. |
X-RateLimit-Reset | Timestamp UNIX en què s'allibera un lloc (una petició surt de la finestra). |
Retry-After | Només en 429. Segons fins que pots reintentar. |
Exemple de capçaleres en una resposta 200:
HTTP/1.1 200 OK
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1747314060I en un 429:
HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1747314007Codi d'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_..."
}
}El code estable identifica quin eix aplicat s'ha exhaurit:
| Eix | Per minut | Per mes |
|---|---|---|
| API key | rate_limit_exceeded | rate_limit_exceeded |
| Empresa | company_rate_limit_exceeded | company_monthly_quota_exceeded |
| Cartera gestionada | portfolio_rate_limit_exceeded | portfolio_monthly_quota_exceeded |
Tots fan servir type: rate_limit_error. Respecta Retry-After quan aparegui;
els errors de cartera també publiquen l'instant o els segons de reintent a
error.details. Els errors d'autenticació repetits es limiten per separat amb
code: too_many_auth_failures.
Bones pràctiques
1. Respecta 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 amb jitter
Per a 5xx, on no hi ha 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. Monitoritza X-RateLimit-Remaining
Si la teva integració s'acosta de manera consistent al 10% del límit, considera:
- Canviar a un pla amb un tier superior.
- Agrupar en lots: en comptes de N POSTs, agrega i fes 1 POST.
- Cachejar lectures freqüents (productes, impostos, sèries).
- Subscriure't a webhooks en comptes de fer polling.
4. Webhooks > polling
Si fas polling de /v1/invoices?status=paid cada minut per detectar pagaments
consumeixes 30 rpm només per a això. Subscriu-te a l'esdeveniment invoice.paid
i redueix-ho a 0 peticions.
5. Claus per integració
Si tens dues integracions (un dashboard intern + un cron d'exportació), crea dues claus diferents: cada clau té els seus propis cubs per minut i mensual, així un cron pesat no consumeix el cubell de la clau del dashboard.
Separar claus no augmenta la capacitat agregada. Els sostres d'empresa i cartera sumen les claus que corresponguin; fes servir més claus per aïllament i atribució, no per esquivar la quota.
Quotes administratives
Algunes càrregues tenen pressupostos de protecció independents de la taxa
de peticions. No consumeixen els cubs de clau/empresa/cartera ni apareixen a
X-RateLimit-*:
| Càrrega | Code estable | Què es mesura |
|---|---|---|
| Enviaments de correu | email_recipient_budget_exceeded | Destinataris diferents dins la finestra, sumats entre credencials. |
| Lliurament de correu | email_delivery_circuit_open | Tall temporal de seguretat del proveïdor/empresa després de fallades de lliurament; no és una quota. |
| Comptes nous | account_probation_limit_exceeded | Capacitat reduïda per antiguitat fins que el compte madura, verifica el cens AEAT o activa una subscripció de pagament. |
| Endpoints PDF | pdf_generation_budget_exceeded | Treball de renderització horari, per empresa o document (subcode). |
| Importacions i pujades | upload_in_flight_budget_exceeded | Bytes temporals travessant el disc alhora, no emmagatzematge ocupat. |
| Exportacions empaquetades | export_budget_exceeded | Documents empaquetats o artefactes generats per hora (subcode). |
Aquests codes responen 429 amb type: rate_limit_error; fes servir
Retry-After o error.details.retry_at quan existeixin. Canviar de credencial
no evita un pressupost d'empresa. Un 402 storage_quota_exceeded diferent
indica que l'emmagatzematge persistent agregat de l'empresa és ple i no
s'allibera esperant. Els límits de quantitat d'endpoints webhook són capacitat
del pla, no un pressupost 429; consulta
Preus.
Pujada de tier
Canviar de tier no requereix rotar claus. Quan el teu pla canvia:
- Les noves quotes apliquen immediatament.
- La quota mensual consumida al tier anterior no es reinicia: només creix el topall mensual.
- Les claus existents conserven el seu
id; el nou tier s'aplica a totes automàticament.
Identitat per enviar documents
L’enviament de documents pot requerir identitat acreditada mitjançant una subscripció activa o una identificació censal acceptada. Les empreses gestionades fan servir la identitat de la gestoria. 422 sender_identity_not_verified requereix corregir aquesta identitat; un 429 correspon a un pressupost d’enviament diferent. Consulta enviament de documents.