Concepts fondamentaux
Erreurs
Chaque réponse 4xx / 5xx de l'API publique suit RFC 7807 — une enveloppe stable unique avec un code lisible par machine sur lequel vous pouvez vous brancher.
Enveloppe
Tous les corps d'erreur ressemblent à ceci :
json{ "type": "https://api.alloovium.com/errors/insufficient_scope", "title": "Insufficient scope", "status": 403, "detail": "API key is missing required scope: vault:write", "instance": "/api/v2/vault/projects", "code": "insufficient_scope", "request_id": "req_01HQZ4R9VYTC5H6NPRDFG8EJUS" }
| Champ | Toujours présent | Description |
|---|---|---|
| type | yes | URI identifying the error category. Based on the code. |
| title | yes | Short human-readable summary. May be translated in the future. |
| status | yes | HTTP status code, duplicated for clients that only parse the body. |
| detail | yes | Longer description with specifics. Safe to log; never contains stack traces. |
| instance | no | Request path that produced the error. |
| code | yes | Stable machine-readable identifier. Branch your code on this. |
| request_id | yes (5xx) | Attach to support tickets for end-to-end trace. |
Branchez sur code, pas sur title
Branchez sur code, pas sur title et detail sont lisibles par l'homme et peuvent changer. Le champ code est couvert par notre contrat de stabilité et ne sera jamais renommé silencieusement.Référence des codes d'erreur
401 — authentification
| Code | Signification |
|---|---|
| missing_api_key | No Authorization header, or not Bearer scheme |
| invalid_api_key | Key does not match any active credential |
| invalid_token | OAuth Bearer JWT is malformed, expired, or signature invalid |
| api_key_revoked | Key was revoked via the dashboard |
| api_key_expired | Key passed its expiry date |
| user_inactive | Owning user has been deactivated |
| tenant_disabled | Owning tenant is suspended |
402 — facturation
| Code | Signification |
|---|---|
| payment_required | Tenant billing is past due. Resolve in the dashboard. |
403 — autorisation
| Code | Signification |
|---|---|
| insufficient_scope | The credential is valid but doesn't carry the required scope. Response includes a missing_scopes array. |
| permission_denied | The user lacks a project- or feature-level permission (e.g. vault:deny_create_project). |
| oauth_not_supported | This capability does not accept OAuth tokens. Call it with an API key. |
json{ "type": "https://api.alloovium.com/errors/insufficient_scope", "title": "Insufficient scope", "status": 403, "detail": "API key is missing required scope: vault:write", "code": "insufficient_scope", "missing_scopes": ["vault:write"] }
404 — non trouvé
| Code | Signification |
|---|---|
| not_found | Resource does not exist, or the caller cannot see it. The API deliberately does not distinguish these two cases so attackers cannot probe cross-tenant IDs. |
409 — conflit
| Code | Signification |
|---|---|
| idempotency_key_reused | Same Idempotency-Key was seen with a different request body in the 24-hour window. |
| idempotency_in_progress | Earlier request with this key is still executing. Retry in a moment. |
413 / 400 — uploads
| Code | Signification |
|---|---|
| file_too_large | Uploaded file exceeds the maximum allowed size. |
| unsupported_file_type | File extension is not in the supported set (pdf, docx, xlsx, pptx, images, etc.). |
| invalid_document_id | A referenced document_id could not be resolved. |
422 — validation
| Code | Signification |
|---|---|
| validation_error | Request payload failed validation. Body includes a field_errors array listing offending fields. |
| invalid_cursor | Pagination cursor was malformed, truncated, or tampered with. |
| invalid_idempotency_key | Idempotency-Key header did not match the allowed pattern (1-255 chars, A-Z a-z 0-9 . _ -). |
429 — limite de débit
| Code | Signification |
|---|---|
| rate_limited | Token bucket exhausted. Body includes retry_after_seconds. See the Rate Limits page for the full retry strategy. |
5xx — serveur
| Code | Signification |
|---|---|
| internal_error | Unexpected server error. Retry with exponential backoff and attach request_id to any support ticket. |
| not_implemented | Endpoint was removed or is not yet implemented in your environment. |
IDs de requête
Chaque réponse — erreur ou succès — porte un header header. Sur les 5xx, le même ID est également intégré dans le corps. Incluez-le lorsque vous contactez le support :
textX-Request-Id: req_01HQZ4R9VYTC5H6NPRDFG8EJUS
Le support peut tracer la requête à travers chaque couche — load balancer, handler FastAPI, requêtes base de données, appels LLM en aval — en utilisant uniquement cet ID.
Erreurs de validation Pydantic (422)
Lorsque le validateur Pydantic de FastAPI rejette un corps de requête avant qu'il n'atteigne un handler, la même enveloppe porte une liste field mappant vers les chemins de champs en échec :
json{ "type": "https://api.alloovium.com/errors/validation_error", "title": "Request validation failed", "status": 422, "detail": "1 field failed validation", "code": "validation_error", "field_errors": [ {"loc": ["body", "name"], "msg": "Field required", "type": "missing"} ] }
Gérer les erreurs dans le code
pythonimport httpx class AllooviumError(Exception): def __init__(self, payload): self.code = payload.get("code") self.status = payload.get("status") self.detail = payload.get("detail") self.request_id = payload.get("request_id") super().__init__(f"{self.code}: {self.detail}") def raise_for_problem(resp: httpx.Response): if resp.is_success: return try: payload = resp.json() except Exception: resp.raise_for_status() return raise AllooviumError(payload) try: resp = httpx.get(url, headers=headers) raise_for_problem(resp) except AllooviumError as e: if e.code == "insufficient_scope": prompt_user_to_grant_scope() elif e.code == "rate_limited": sleep_and_retry() else: log.error("Alloovium call failed", code=e.code, request_id=e.request_id) raise
Voir aussi
- Limites de débit — stratégie de retry complète pour 429 et 5xx.
- Idempotence — comment éviter que les retries créent des doublons.