Docs/API et Webhooks/Erreurs et réponses

Erreurs et réponses

Chaque point de terminaison de l'API publique renvoie des formes de réponse prévisibles. Les erreurs portent un code lisible par machine stable dans le corps pour que vous puissiez vous brancher dessus sans analyser l'anglais.

Enveloppe de réponse

Les réponses réussies renvoient la ressource (ou une liste de ressources) directement. Il n'y a pas d'enveloppe de haut niveau — les clients peuvent désérialiser directement dans un modèle typé :

GET /api/public/v1/org

{
  "id": "e188fc87-…",
  "name": "Acme Corp",
  "plan": "growth",
  …
}

Les réponses d'échec utilisent une petite forme uniforme avec un code error comme seul champ requis. Les champs optionnels donnent un contexte qui aide à corriger l'appel :

{
  "error": "insufficient_scope",
  "required": "assignments:write",
  "present": ["assignments:read", "users:read"]
}

Référence des codes de statut

StatutQuand vous le voyezQue faire
200Requête réussie. Le corps contient la ressource ou un message de confirmation.Traitez le corps.
400Requête malformée : champ requis manquant, valeur d'énumération invalide, corps trop volumineux, JSON non analysable.Corrigez la requête client — ne réessayez pas la même charge utile.
401Token manquant, malformé, révoqué ou expiré.Vérifiez l'en-tête Authorization. Faites tourner le token s'il a été révoqué.
403Le token est valide mais manque de la portée requise.Ajoutez la portée dans l'interface admin ; la réponse porte le nom exact de la portée.
404La ressource n'existe pas ou appartient à une organisation différente.Récupérez à nouveau la collection parent. Ne suivez pas les IDs obsolètes à travers les organisations.
409Conflit — par exemple, un e-mail est déjà utilisé.Traitez comme un succès si votre opération est idempotente.
413Le corps de requête dépasse le plafond par point de terminaison. Renvoyé par Kestrel pour un dépassement dur ; le point de terminaison SARIF renvoie aussi ceci en tant que 400 body_too_large lorsque le Content-Length déclaré dépasse 10 Mo.Réduisez la charge utile. Pour SARIF, ingérez par incrément les découvertes d'un outil à la fois.
429Limite de débit atteinte sur cette clé API.Honorez Retry-After ; voir Limites de débit.
5xxProblème côté serveur.Réessayez avec backoff exponentiel. Capturez l'en-tête X-Request-Id de la réponse et citez-le dans tout ticket de support.

Codes d'erreur

Le champ error est stable à travers les versions — branchez-vous dessus dans le code client plutôt que sur le statut HTTP, car le même statut peut porter différents codes :

CodeStatutSignification
unauthorized401Aucun token bearer utilisable sur la requête.
insufficient_scope403Le token est correct, la portée manque. La réponse inclut required et present.
rate_limited429Plafond dépassé. Voir l'en-tête Retry-After.
user_not_found404L'ID utilisateur n'existe pas ou n'est pas dans votre organisation.
team_not_found404L'ID équipe n'existe pas ou n'est pas dans votre organisation.
assignment_not_found404L'ID affectation n'existe pas ou n'est pas dans votre organisation.
empty_body400POST ou PATCH envoyé sans corps là où un est requis.
body_too_large400 / 413Le corps de requête a dépassé le plafond du point de terminaison. SARIF émet ceci comme 400 avec maxBytes dans le corps lorsque le Content-Length déclaré est trop volumineux ; Kestrel émet un 413 nu lorsque le corps dépasse réellement.

IDs de requête

Chaque réponse porte un en-tête X-Request-Id (UUID v4). Capturez-le côté client et incluez-le dans les requêtes de support — il nous permet de tirer la trace côté serveur exacte pour l'appel en échec. Pour les réponses 5xx, l'ID de requête est le chemin unique le plus rapide vers le diagnostic.

Erreurs de validation

Les échecs de validation sur les corps POST et PATCH renvoient 400 avec un error plat décrivant la première règle qui échoue. La surfacing de validation multi-champs ne fait pas partie de v1 — corrigez le premier champ rapporté et réessayez. Les futures versions peuvent ajouter des détails par champ ; le contrat error de haut niveau restera.

Branchement sur les erreurs — exemple

const res = await fetch(url, { headers });
if (res.ok) return res.json();

const body = await res.json().catch(() => ({}));
switch (body.error) {
  case 'rate_limited':
    return retryWithBackoff(url);
  case 'insufficient_scope':
    throw new Error(`API key missing scope: ${body.required}`);
  case 'unauthorized':
    throw new Error('API key revoked or invalid — rotate the secret');
  default:
    throw new Error(`API error ${res.status}: ${body.error || 'unknown'}`);
}