Límits de peticions
Quotes per clau, empresa i cartera del compte 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 del compte — el compte al qual pertany la credencial, només quan aquest compte té dos o més NIF reals.
Els límits depenen del tier de la teva API key. El tier es deriva del pla
del teu compte: 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 continuï actiu un pla 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 Esencial. |
| Pro | 300 | 50.000 | 900 | 150.000 | Els plans Profesional i Avanzado. |
| Scale | Segons contracte | Segons contracte | Segons contracte | Segons contracte | 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, i els sostres per minut abans que els mensuals. 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.
La cartera del compte
El tercer eix és del compte de la credencial, no del NIF que anomena una petició. Una credencial opera una cartera quan el seu propi compte té almenys dos NIF reals. La sandbox del compte no compta, així que un NIF titular i la seva sandbox no són una cartera, i els NIF arxivats tampoc no compten. Amb un sol NIF real aquest eix no s'aplica mai: les peticions segueixen els sostres de clau i d'empresa de dalt i res més.
Dues regles decideixen on compta una petició:
- Un NIF al qual s'arriba per una relació compta a la teva cartera. Una petició sobre un NIF que un altre compte posa al teu abast, per un accés cedit o per un compte gestionat, suma a la cartera del compte de la teva credencial i al sòl reservat del NIF que anomena. Mai no suma a la cartera del compte propietari d'aquest NIF.
- Un NIF que surt del compte canvia de sostre. Quan un NIF passa a un altre compte per un traspàs de NIF, les peticions sobre ell deixen de comptar a la cartera del compte que abandona i compten a la cartera del seu compte nou, a través de les credencials d'aquell compte. Que un compte operi o no una cartera es recorda durant aproximadament un minut, així que un canvi en el nombre de NIF d'un compte arriba als sostres dins d'aquell minut.
Una cartera té un catàleg pla independent per tier:
| Tier | Banda comuna/min | Sòl reservat per NIF/min | Cartera/mes | Claus actives al compte |
|---|---|---|---|---|
| Free | 10 | 10 | 100 | 1 |
| Starter | 180 | 20 | 150.000 | 15 |
| Pro | 1.800 | 30 | 1.500.000 | 500 |
| Scale | Segons contracte | Segons contracte | Segons contracte | Segons contracte |
El sòl reservat d'un NIF s'avalua primer. Un NIF 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. Cap dels quatre valors no depèn de quants NIF tingui el compte.
Els sostres de cartera per minut i mensual encara no estan en vigor:
funcionen ara en mode d'observació (shadow), pendents de calibració amb
trànsit real de tancament. Mesuren els rebutjos que haurien produït sense
retornar 429, i mentre només observen, el sostre per clau continua aplicant-se
com abans.
El topall de claus funciona diferent: es comprova en crear una clau, no a cada petició, i ja està en vigor. S'aplica a una cartera, perquè un compte amb un sol NIF només es troba amb el topall per empresa, i va a més d'aquest topall, que es comprova primer. Compta totes les credencials del compte que no s'han revocat, incloses les claus de proves. Una clau caducada que ningú no va revocar continua ocupant el seu lloc, així que revoca les claus que ja no facis servir. Un compte que ja supera el topall conserva totes les seves claus: només es rebutgen les noves.
Els rebutjos de cartera fan servir portfolio_rate_limit_exceeded i
portfolio_monthly_quota_exceeded, i una clau creada per sobre del topall
respon 422
portfolio_max_api_keys_exceeded.
Donar d'alta més NIF 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, i mai als tres errors de quota mensual. Segons fins que pots reintentar. Un comptador mensual es renova en començar el mes natural següent. |
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 per minut:
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 | monthly_quota_exceeded |
| Empresa | company_rate_limit_exceeded | company_monthly_quota_exceeded |
| Cartera del compte | portfolio_rate_limit_exceeded | portfolio_monthly_quota_exceeded |
Tots fan servir type: rate_limit_error. Respecta Retry-After en els de per
minut. Els mensuals no porten Retry-After: el comptador es renova en començar
el mes natural següent, així que esperar uns segons no els resol. 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)Els tres errors de quota mensual no porten Retry-After. Un 429 mensual no es
resol esperant uns segons: deixa de reintentar-lo i ramifica segons error.code.
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/companies/{company}/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 el compte ha arribat al seu ús màxim; no s'allibera esperant: escriu a suport.
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. Un NIF que no és el titular la pren del NIF titular del seu compte, i els NIF d’un compte gestionat la prenen del NIF titular del compte del proveïdor mentre duri la gestió. 422 sender_identity_not_verified requereix corregir aquesta identitat; un 429 correspon a un pressupost d’enviament diferent. Consulta enviament de documents i la identitat d’enviament d’un NIF.