Skip to content

Erreurs — Public API ​

Format de réponse d'erreur ​

Toutes les erreurs renvoient un JSON avec au minimum les champs error (message lisible) et code (énuméré machine).

json
{
  "error": "Permission denied. Required scope: clients:write",
  "code": "PERMISSION_DENIED",
  "required": "clients:write"
}

Champs additionnels possibles selon le code :

  • details (objet) : sortie de zodError.flatten() pour les VALIDATION_FAILED
  • required (string) : scope manquant pour PERMISSION_DENIED
  • retryAfter (number, secondes) : pour RATE_LIMIT_EXCEEDED
  • upgradeUrl (string) : pour PLAN_UPGRADE_REQUIRED

Codes d'erreur énumérés ​

Source : server/publicApi/types.ts:19-32

HTTPCodeCauseAction
401MISSING_API_KEYHeader x-api-key absent ou ne commence pas par spk_Ajouter le header
401INVALID_API_KEYClé inconnue ou inactiveVérifier la clé / en générer une nouvelle
401EXPIRED_API_KEYClé expirée (expiresAt dépassé)Générer une nouvelle clé
401REVOKED_API_KEYClé révoquée par adminDemander une nouvelle clé
403IP_NOT_ALLOWEDIP appelante absente de l'IP whitelistWhitelister l'IP ou retirer la restriction
403PLAN_UPGRADE_REQUIREDPlan agence n'a pas api_access activéUpgrade du plan (voir upgradeUrl)
403PERMISSION_DENIEDLa clé n'a pas le scope requisRégénérer une clé avec le bon scope
429RATE_LIMIT_EXCEEDEDLimite par minute ou par jour atteinteAttendre retryAfter, voir rate-limiting.md
400VALIDATION_FAILEDBody invalide (Zod)Corriger le payload, voir details
404NOT_FOUNDRessource introuvable ou hors agenceVérifier l'ID
500INTERNAL_ERRORErreur serveur génériqueRéessayer avec backoff, contacter support si persistant
500AUTH_ERRORErreur lors de la résolution de la clé (DB)Réessayer, contacter support si persistant

Exemples par code ​

401 MISSING_API_KEY ​

http
GET /api/public/v1/clients
json
{
  "error": "API key required. Provide it in the 'x-api-key' header.",
  "code": "MISSING_API_KEY"
}

403 PERMISSION_DENIED ​

http
POST /api/public/v1/clients
x-api-key: spk_<key sans clients:write>
json
{
  "error": "Permission denied. Required scope: clients:write",
  "code": "PERMISSION_DENIED",
  "required": "clients:write"
}

400 VALIDATION_FAILED ​

http
POST /api/public/v1/clients
{ "name": "" }
json
{
  "error": "Données invalides",
  "details": {
    "fieldErrors": {
      "name": ["String must contain at least 1 character(s)"]
    },
    "formErrors": []
  }
}

Note : actuellement les handlers CRM renvoient { error: "Données invalides", details: ... } sans le code VALIDATION_FAILED explicite. Le code énuméré est documenté pour cohérence future.

404 NOT_FOUND ​

http
GET /api/public/v1/clients/99999
json
{ "error": "Ressource introuvable" }

Multi-tenant : un ID existant mais appartenant à une autre agence renvoie aussi 404 (jamais 403) pour ne pas leak l'existence de la ressource.

429 RATE_LIMIT_EXCEEDED ​

Voir rate-limiting.md.

500 INTERNAL_ERROR ​

json
{ "error": "Erreur interne" }

Aucun détail technique n'est exposé (pas de stack trace, pas de message DB). Logs serveur consultables côté admin.

Stratégie de gestion d'erreur côté client ​

CodeRetry ?Backoff
401 (auth)NonVérifier la config
403 (permission/plan/IP)NonVérifier la config
429 (rate limit)OuiRespecter Retry-After
400 (validation)NonCorriger le payload
404NonVérifier l'ID
500/502/503/504OuiBackoff exponentiel + jitter, max 3-5 tries

Idempotence ​

Les opérations idempotentes :

  • Toutes les GET
  • DELETE (un 2e DELETE renvoie 404, ce qui est sûr)
  • PUT (remplacement complet — même résultat sur retry)

Les opérations non idempotentes :

  • POST : un retry peut créer un doublon. Pour les imports critiques, vérifiez si la ressource existe avant de créer.

Roadmap : un header Idempotency-Key (UUID v4) est envisagé pour rendre les POST idempotents — pas encore implémenté.

Versionning et stabilité ​

L'API publique est versionnée dans le path : /api/public/v1/*. Les codes d'erreur ci-dessus font partie du contrat stable. Tout nouveau code sera ajouté à ce document avec sa date d'introduction. Voir changelog.md.

StormeoOS API