Chaque refus de l’API REST de gestion est un corps JSON accompagné d’un statut HTTP. Cette page explique comment le lire, quelles limites existent et comment votre intégration doit réagir.
Le corps d’erreur
La plupart des erreurs ressemblent à ceci :
{
"message": "The device limit of this account is reached.",
"code": "FORBIDDEN",
"details": { "key": "max_devices", "limit": 43, "current": 43, "adding": 1 }
}
| Champ | Signification |
|---|---|
message | Une phrase en anglais destinée aux personnes. Ne pas l’analyser : elle peut changer. |
code | Un code stable pour le type d’erreur (tableau ci-dessous) |
details | Présent lorsque le client peut agir davantage : reason (un code machine stable), key (une limite de forfait), keys, issues |
Variantes :
| Cas | Corps |
|---|---|
| Un corps ou une requête qui enfreint une règle de champ | 400 { "message": "Validation error", "issues": [{ "path": ["name"], "message": "…" }] } |
| Certaines routes vérifient elles-mêmes le corps | 400 { "message": "<the problems, joined with commas>" } |
| JSON mal formé | 400 { "message": "Malformed request body" } |
| Une erreur serveur inattendue | 500 { "message": "Internal server error" } (la cause est journalisée de notre côté, non affichée) |
Testez d’abord le statut, puis code et details.reason. Chaque référence de route énumère ses motifs.
Codes de statut
| Statut | Signification | Que faire |
|---|---|---|
| 200, 201 | Succès (201 : créé) | |
| 202 | Accepté, toujours en cours d’exécution (une commande) | Lire le résultat plus tard |
| 400 | La requête n’est pas valide | Corrigez la requête ; ne la relancez pas telle quelle |
| 401 | Aucun identifiant valide : « Invalid or expired API key. » | Vérifiez la clé ; ne relancez pas |
| 403 | La clé ou son titulaire ne peut pas effectuer cette action, la clé n’est pas autorisée depuis cette adresse, ou une limite de forfait est atteinte | Vérifiez les permissions de la clé et le rôle du titulaire ; pour details.key, le forfait |
| 404 | Introuvable, ou non visible pour vous | Vérifiez l’identifiant et les permissions de la clé |
| 405 | La méthode n’est pas autorisée ici (par exemple, écrire des attributs client) | |
| 409 | Un conflit : un doublon, un enregistrement encore utilisé, un état qui ne permet pas l’action, ou une modification faite par quelqu’un d’autre | Relire, puis décider |
| 412 | L’enregistrement a changé depuis votre lecture (If-Match) | Relisez et réappliquez votre modification |
| 413 | Le corps ou le fichier est trop volumineux | Envoyez moins de données |
| 415 | Content-Type incorrect (serveurs MCP) | Envoyez application/json |
| 422 | Le contenu enfreint une règle métier | Corrigez le contenu |
| 428 | Un en-tête de précondition requis est absent (If-Match) | Envoyez-le |
| 429 | Une limite de débit | Attendez Retry-After secondes, puis relancez |
| 500 | Une erreur de notre côté | Relancez plus tard avec un délai croissant |
| 503 | Indisponibilité temporaire, par exemple lorsque votre organisation est en cours de migration : « This workspace is read-only while it is being moved. Please try again later. » (code TENANT_READ_ONLY, Retry-After: 300) | Relancez après Retry-After ; les lectures continuent de fonctionner |
Codes
code | Statut typique |
|---|---|
VALIDATION_ERROR | 400, 413, 422, 428 |
UNAUTHORIZED | 401 |
FORBIDDEN | 403 |
FEATURE_NOT_AVAILABLE | 403 : votre forfait n’inclut pas cette fonctionnalité |
TENANT_SUSPENDED, TENANT_INACTIVE | 403 : votre organisation n’est pas active |
TENANT_IP_NOT_ALLOWED | 403 : les règles IP de votre organisation refusent cette adresse |
NOT_FOUND | 404 |
CONFLICT | 409, 412 |
RATE_LIMIT_EXCEEDED | 429 |
INTERNAL_ERROR | 500, 503 |
Limites de forfait
Une limite de forfait est un 403 dont details.key nomme la limite, details.limit indique sa valeur et details.current votre nombre actuel, par exemple max_devices lorsque vous créez un appareil. Voir Usage and quotas et Plans and the IoT add-on.
Limites de débit
Plusieurs limites s’appliquent à chaque appel avec clé d’API. Chacune répond 429 lorsqu’elle est épuisée.
| Limite | Par défaut | Portée | Message |
|---|---|---|---|
| Limite par adresse | 120 requêtes par minute, jusqu’à 120 simultanées | Par adresse IP appelante | « Too many requests. Please try again later. » |
| Limite de forfait | Définie par votre forfait (aucune si le forfait n’en définit pas) | Par organisation, toutes les clés et les membres connectés ensemble | « Your plan’s API rate limit has been reached. Please try again shortly or upgrade your plan. » |
| Limite de clé | 1 000 appels par minute d’horloge (Per-Key Rate Limit dans les paramètres de la clé d’API) | Par clé | « API key rate limit exceeded. Please slow down. » |
Certaines routes ajoutent leurs propres limites :
| Route | Limite |
|---|---|
| Commandes | 10 par appareil par minute (« Too many commands to this device; try again in a minute. », Retry-After: 60) ; 600 par organisation par minute (« Too many requests for your plan. Please upgrade or try again later. », X-RateLimit-Scope: tenant-plan) |
| Écritures des paramètres d’appareil | 600 par organisation par minute |
| Serveurs MCP | 120 appels d’outils en lecture et 20 en écriture par identifiant et par minute |
En-têtes sur un 429
| En-tête | Signification |
|---|---|
Retry-After | Secondes avant qu’un appel ne soit de nouveau accepté |
RateLimit-Limit, X-RateLimit-Limit | La limite par minute |
RateLimit-Remaining, X-RateLimit-Remaining | Appels restants (0) |
RateLimit-Reset | Secondes avant que le seau ne soit de nouveau plein |
Tous les 429 ne portent pas tous ces en-têtes. Si Retry-After est absent, attendez 60 secondes.
La limite par adresse se recharge en continu : un appel revient toutes les demi-secondes, donc un rythme constant de 2 appels par seconde ne l’atteint jamais. Répartissez les rafales au lieu de les envoyer d’un coup.
Relancer en toute sécurité
- Ne relancez que les
429,500,502,503et504, ainsi que les erreurs réseau. - Attendez
Retry-Afterlorsqu’il est présent ; sinon, espacez les tentatives de façon exponentielle (1, 2, 4, 8 … secondes, jusqu’à une minute) avec une gigue aléatoire. - Abandonnez après quelques tentatives et journalisez le dernier corps.
- Avant de relancer un
POSTqui crée quelque chose (un appareil, une commande), vérifiez si le premier appel a pris effet : listez ou lisez d’abord. UnPOSTde commande n’a pas de clé d’idempotence. - Ne relancez jamais
400,401,403,404ou422sans modification.
async function call(url, init, tries = 5) {
for (let i = 0; ; i++) {
const res = await fetch(url, init);
if (res.ok || i === tries - 1 || ![429, 500, 502, 503, 504].includes(res.status)) return res;
const wait = Number(res.headers.get('Retry-After')) || Math.min(60, 2 ** i) + Math.random();
await new Promise((r) => setTimeout(r, wait * 1000));
}
}
Erreurs que vous rencontrerez en premier
| Vous voyez | Cause probable |
|---|---|
401 sur chaque appel | Une faute de frappe dans la clé, une clé expirée ou révoquée, ou une clé d’une autre organisation (le tenantId dans le chemin doit être celui de la clé) |
403 « API key does not have the required permission. » | La clé n’a pas la permission de la route. Modifiez les Module permissions de la clé. |
403 « You are not permitted to perform this action » | La clé possède la permission, mais son titulaire ne l’a plus (rôle modifié, groupe retiré, politique d’accès) |
403 « This API key may not be used from the current IP address. » | La liste d’autorisation IP de la clé, ou la liste par défaut de l’organisation |
404 pour un enregistrement visible dans l’application | Le titulaire de la clé le voit grâce à une permission que la clé ne possède pas, ou l’identifiant appartient à une autre organisation |
429 depuis un seul serveur | La limite par adresse : répartissez les appels ou utilisez moins de pages, mais plus grandes |

