Alloovium

Concepts fondamentaux

Limites de débit

Alloovium exécute un token bucket par identifiant. Chaque capability a un coût en tokens ; chaque niveau a un taux de remplissage et une capacité de burst maximale. Restez dans votre bucket et vous ne verrez jamais un 429.

Comment fonctionne le bucket

Chaque clé API et identifiant OAuth a son propre token bucket. Les tokens se remplissent continuellement au taux par minute du niveau, jusqu'à la capacité de burst du niveau. Quand une requête arrive, le coût de la capability est déduit du bucket. Si le bucket n'a pas assez de tokens, la requête est rejetée avec code et doit être retentée plus tard.

Token-bucket, pas fenêtre fixe

Une limite de fenêtre fixe à 60/min permettrait 120 appels en bordure de fenêtre. Un token bucket avec un taux de 60 et un burst de 120 lisse cela : vous pouvez faire un burst à 120 instantanément, mais le trafic soutenu est en moyenne de 60/minute.

Niveaux

NiveauTokens / minuteCapacité de burstUsage typique
free1020Hobby projects and prototyping
standard60120Most SaaS integrations
pro300600High-volume automations and ETL
enterprise15003000Platform integrations, custom SLAs

Le niveau est défini sur chaque clé API lors de la création et peut être mis à niveau depuis le tableau de bord. Les identifiants OAuth héritent du niveau du plan de tenant de l'utilisateur.

Coûts des capabilities

Les lectures bon marché coûtent 1 token. Les recherches et requêtes structurées coûtent 5. Le chat et les appels LLM coûteux coûtent 10. Les exécutions de workflow et les remplissages de template coûtent 25. Utilisez ce tableau pour budgétiser :

CapabilityCoût
meta.whoami1
vault.list_projects1
vault.get_project1
vault.create_project2
vault.list_documents1
vault.get_document1
vault.upload_document10
vault.search5
chat.list_conversations1
chat.get_conversation1
chat.ask10
chat.ask_stream10
templates.start_fill25
templates.get_fill_status1
workflows.list1
workflows.run25
workflows.get_run_status1

Headers de réponse

Chaque réponse — succès ou limite de débit — porte ces headers :

HeaderSignification
X-RateLimit-LimitBurst capacity of your bucket
X-RateLimit-RemainingTokens left after this call was accounted for
X-RateLimit-ResetUnix timestamp when the bucket is expected to be full
X-RateLimit-CostTokens this particular call deducted
Retry-AfterSeconds until you can retry (only on 429)

Surveillez header de manière proactive et ralentissez avant d'atteindre zéro — vous obtiendrez un comportement plus propre qu'en réagissant aux 429.

Atteindre la limite

Quand vous manquez de tokens, l'API retourne code avec cette enveloppe :

json
{ "type": "https://api.alloovium.com/errors/rate_limited", "title": "Rate limit exceeded", "status": 429, "detail": "Rate limit exceeded. Retry in 12 seconds.", "code": "rate_limited", "retry_after_seconds": 12 }

Le header header porte la même valeur. Respectez-le. Ne retentez pas immédiatement dans une boucle serrée — cela prolongerait seulement le backoff et gaspillerait votre quota.

Stratégie de retry

La stratégie recommandée pour tout client :

  1. Sur 429, attendez header secondes et retentez.
  2. Sur 5xx, retentez avec backoff exponentiel — commencez à 1s, doublez jusqu'à 30s, ajoutez 10% de jitter. Limitez à cinq tentatives.
  3. À chaque retry, conservez le même header afin que l'API puisse rejouer la réponse originale au lieu de s'exécuter deux fois. Voir Idempotence.
  4. Abandonnez après des erreurs 4xx non-429 répétées — celles-ci ne sont pas transitoires.

Exemple de boucle de retry (pseudocode)

python
import time, httpx def call_with_retry(client, method, url, *, body=None, idem_key=None, max_retries=5): headers = {"Authorization": f"Bearer {API_KEY}"} if idem_key: headers["Idempotency-Key"] = idem_key for attempt in range(max_retries): resp = client.request(method, url, json=body, headers=headers) if resp.status_code < 400: return resp.json() if resp.status_code == 429: time.sleep(int(resp.headers.get("Retry-After", "1"))) continue if 500 <= resp.status_code < 600: time.sleep(min(30, 2 ** attempt) + (0.1 * attempt)) continue # 4xx other than 429 — do not retry resp.raise_for_status() raise RuntimeError("max retries exhausted")

Conseils d'ingénierie de quota

  • Groupez avec search (coût 5) plutôt que plusieurs appels get (coût 1 chacun) lorsque vous avez besoin du contenu.
  • Pour les workflows, interrogez status toutes les 2–5 secondes — ne faites pas de boucle serrée.
  • Si vous ingérez en fan-out, exécutez les appels upload en concurrent jusqu'à formula, puis attendez que le bucket se remplisse.
  • Utilisez whoami (coût 1) comme sonde de santé — pas les endpoints plus coûteux.