Référence API

Erreurs et codes de réponse

Ce que l’API renvoie quand elle refuse, comment le lire, et lesquels de ces refus méritent une nouvelle tentative.

Le format : RFC 7807

Toute erreur porte le même corps, quel que soit le point de terminaison. Il n’y a pas d’objet error imbriqué, et pas de champ code.

{
  "type": "about:blank",
  "title": "Forbidden",
  "status": 403,
  "detail": "missing 'keys:wrap' permission"
}

title reprend la classe d’erreur, status le code HTTP, detail le motif précis. C’est detail qui distingue les trois cas de 403, et c’est donc lui qu’il faut journaliser.

Le seul symbole : E_ENVELOPE_ONLY

Une seule erreur porte un identifiant symbolique, et il vit dans detail, pas dans un champ dédié. C’est de loin celle que vous rencontrerez le plus souvent en intégrant.

{
  "type": "about:blank",
  "title": "Forbidden",
  "status": 403,
  "detail": "E_ENVELOPE_ONLY: ce locataire est en mode enveloppe, ou la donnee
             en clair ne transite jamais par MAFATE. Les operations serveur
             /v1/encrypt et /v1/decrypt sont donc refusees. Chiffrez en local
             avec une cle de donnees et utilisez /v1/keys/{id}/wrap et
             /v1/keys/{id}/unwrap, ou ecrivez a [email protected] pour activer
             le mode serveur sur ce locataire."
}

Ce refus est journalisé sous l’action envelope_only.refused, avec le chemin et la méthode. Réessayer en boucle ne débloque rien et remplit votre journal d’audit de refus : c’est un état de compte, pas un incident passager.

Les huit réponses possibles

400Bad Request

JSON malformé, champ requis absent, base64 non conforme, ou clé de données qui ne fait pas exactement 32 octets.

Corriger la requête. Ne pas réessayer : le résultat sera identique. Le contrôle des 32 octets est strict par choix, accepter 16 octets dégraderait silencieusement l’AES-256 annoncé.

401Unauthorized

Clé API absente, inconnue, expirée ou révoquée. Également renvoyé si le locataire de la clé est introuvable.

Vérifier l’en-tête Authorization et l’état de la clé dans votre tableau de bord.

403Forbidden

Trois situations distinctes partagent ce statut : permission manquante sur la clé API, jeton wrapped_key non authentifiable pour la clé visée, ou appel à /v1/encrypt et /v1/decrypt sur un locataire en mode enveloppe.

Lire le champ detail, qui les distingue. Aucune des trois ne se résout en réessayant.

404Not Found

La clé n’existe pas pour ce locataire.

Vérifier que vous passez bien l’UUID rendu par POST /v1/keys, et non le nom lisible de la clé. C’est la cause la plus fréquente de ce statut.

409Conflict

Nom de clé déjà pris sur le locataire, ou opération refusée par l’état de la clé : seule une clé active peut tourner, emballer ou hacher.

Sur une clé désactivée, ce statut est définitif : la destruction des clés de données est irréversible.

422Decryption Failed

Mode serveur uniquement. Le chiffré a été altéré, la clé ne correspond pas, ou le tag GCM ne vérifie pas.

En mode enveloppe, l’équivalent se produit chez vous, à la vérification du tag, sans appel réseau.

429Quota Exceeded

Quota mensuel d’opérations atteint. Uniquement sur /v1/encrypt.

Ce n’est pas une limite de débit et attendre quelques secondes ne changera rien. Le déchiffrement, lui, n’est jamais refusé pour cause de quota : un quota ne doit pas vous enfermer hors de vos propres données.

500Internal Server Error

Erreur interne. Un cas mérite d’être connu : unwrap refuse de rendre la clé de données si son entrée d’audit n’a pas pu être écrite.

Ce refus est délibéré, pas un incident de plus : sans trace confirmée, une sortie de clé serait invisible. Le message est explicite, « unwrap refused: audit trail could not be recorded ».

Que réessayer, et que ne pas réessayer

La règle tient en une phrase : réessayez ce que le serveur n’a pas décidé.

SituationRéessayer ?
Réseau coupé, délai dépassé, aucune réponseOui, avec temporisation exponentielle
500, 502, 503Oui, sauf le refus d’audit d’unwrap, qui persistera tant que la base n’écrit pas
4xx, quel qu’il soit, y compris 429Non. Une décision ne devient pas un accord à la troisième tentative.

Côté SDK, la distinction est portée par des classes distinctes : ApiError quand le serveur a répondu, avec status, title et detail ; ConnectionError et TimeoutError quand il n’a rien répondu, donc sans statut à interpréter. Les confondre pousse à réessayer là où il faut corriger une configuration, ou l’inverse.