API REST / Codes d'erreur
Codes d'erreur
Référence complète des erreurs HTTP retournées par l'API REST Normi.
Format de réponse
Toutes les erreurs retournent un objet JSON avec un champ error structuré :
{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits. Required: 5, available: 3. Free credits reset to 500 on 2026-11-01 (UTC). Buy credits at https://www.normi.fr/dashboard/credits.",
"upgrade_url": "https://www.normi.fr/dashboard/credits",
"free_credits_reset_at": "2026-11-01T00:00:00.000Z"
}
}MCP vs REST
En REST, les erreurs sont signalées par le code HTTP (402, 429, etc.) et le corps JSON ci-dessus. En MCP, la plupart des erreurs (crédits insuffisants, capacité) sont retournées comme texte dans
content[0].text — pas comme erreur HTTP. Côté MCP, seules l'authentification (401, 403 no_active_key, 503 de vérification du jeton) et la limite de débit (429) sont des erreurs HTTP.Tableau de référence
| HTTP | code | Cause |
|---|---|---|
| 400 | invalid_params | Validation Zod échouée — paramètre manquant, type incorrect ou valeur hors plage. |
| 400 | missing_location | Aucun filtre de localisation fourni (code_postal, commune, code_departement ou lat+lon). |
| 401 | missing_bearer_token | Aucun header X-API-Key ni Authorization: Bearer présent dans la requête. Sur le serveur MCP, la réponse porte aussi un en-tête WWW-Authenticate qui déclenche la connexion OAuth (voir plus bas). |
| 401 | unknown_key | Le token n'existe pas dans la base de données (hash SHA-256 introuvable). |
| 401 | inactive_key | Le token a été révoqué (is_active = false). Créez un nouveau token dans le dashboard. |
| 402 | insufficient_credits | Solde de crédits insuffisant pour exécuter la requête. Le corps ajoute upgrade_url (page d'achat de crédits) et, pour un token gratuit, free_credits_reset_at (prochaine remise à 500, le 1er du mois à 00:00 UTC). |
| 403 | plan_required | Fonctionnalité réservée aux plans Scale/Enterprise (ex. alertes webhook). |
| 404 | not_found | Ressource introuvable (transaction, alerte, bien du portefeuille). Les crédits sont remboursés automatiquement sur les endpoints directs (:id). |
| 429 | rate_limited | Limite de débit dépassée pour votre plan. Voir la page Limites de débit pour les seuils par plan. |
| 503 | at_capacity | Le serveur a atteint sa limite de 15 requêtes DB simultanées. Réessayez après quelques secondes. |
| 503 | service_unavailable | La base de données n'est pas configurée (variable d'environnement manquante). Erreur d'infrastructure. |
| 500 | query_failed | La requête SQL a levé une exception inattendue. |
Serveur MCP : erreurs de connexion OAuth
Sur POST https://mcp.normi.fr/mcp, une connexion OAuth peut renvoyer les erreurs suivantes, au format { "error": "<code>", "message": "…" }. L'API REST /v1 n'accepte pas les jetons OAuth.
| HTTP | error | Cause |
|---|---|---|
| 401 | missing_bearer_token | Aucun identifiant. L'en-tête WWW-Authenticate: Bearer resource_metadata="https://mcp.normi.fr/.well-known/oauth-protected-resource/mcp" indique au client où se connecter. |
| 401 | invalid_token | Jeton expiré (le client doit le rafraîchir), autorisation révoquée par l'utilisateur, ou jeton invalide. Le motif est dans message et dans l'en-tête WWW-Authenticate. |
| 403 | no_active_key | Jeton valide, mais le compte n'a plus de clé API active (révoquée sans remplaçante). Créez une clé dans le dashboard : l'application reprend à l'appel suivant, sans reconnexion. |
| 503 | service_unavailable | Vérification du jeton momentanément impossible. Réessayez ; ne relancez pas l'autorisation. |
Recommandations client
- 401 : ne réessayez pas automatiquement — le token est invalide ou révoqué. Affichez une erreur à l'utilisateur.
- 402 : vérifiez le solde avant d'appeler des endpoints coûteux. Le champ
_credits.remainingest inclus dans chaque réponse réussie. - 429 : implémentez un backoff exponentiel (1s, 2s, 4s). La limite est une fenêtre glissante de 60 secondes.
- 503 at_capacity : le serveur est saturé (15 requêtes DB simultanées). Réessayez après 2–5 secondes avec backoff.
- 404 sur :id : les crédits sont automatiquement remboursés sur
GET /v1/transactions/:idetGET /v1/businesses/:sirenquand la ressource est introuvable.
Détecter la limitation automatique
Une requête réussie (HTTP 200) peut contenir un champ
notice indiquant qu'un filtre de date a été appliqué automatiquement (ex. rayon > 1000 m → 12 derniers mois). Ce n'est pas une erreur, mais cela signifie que les résultats sont restreints. En savoir plus sur les filtres automatiques.