Codes d’erreur et de réponse
L’API Discuse signale les problèmes de deux façons : un statut d’erreur HTTP accompagné d’un message, ou une réponse normale 200 dont les champs indiquent ce qui s’est passé. Cette page recense tous les cas afin que vous puissiez les gérer correctement — et explique celui qui prête souvent à confusion : l’épuisement du quota de facturation n’est pas une erreur HTTP.
Quels statuts HTTP l’API renvoie-t-elle ?
| Statut | Quand | Que faire |
|---|---|---|
200 |
Succès — y compris le cas du « quota épuisé » | Inspecter le corps de la réponse ; un 200 n’est pas toujours un feu vert (voir ci-dessous) |
400 |
Échec de la validation de la requête — contenu vide, text de plus de 10 000 caractères, ou trop d’URL de médias |
Corriger la requête ; ne pas réessayer sans modification |
401 |
Clé API manquante ou invalide | Vérifier l’en-tête X-API-Key ; ne pas réessayer sans modification |
429 |
Limite de débit dépassée pour la clé | Temporiser, puis réessayer après la fenêtre d’une minute |
500 |
Erreur interne ou d’un service en aval | Réessayer avec un backoff |
Lisez le message de toute réponse non-2xx. Les échecs d’authentification renvoient 401, les dépassements de limite de débit renvoient 429, et les échecs de validation de requête renvoient 400 ; traitez les 5xx comme transitoires et réessayez avec un backoff.
Pourquoi le « quota épuisé » est-il un 200, et non une erreur ?
Lorsqu’un projet a consommé son quota mensuel de requêtes API, POST /api/v2/check renvoie tout de même 200 — avec le contenu considéré comme ne présentant aucune violation, un message expliquant que le quota est épuisé, et un objet usage indiquant qu’il ne reste aucune requête :
{
"has_violations": false,
"message": "API quota exceeded. Current: 10000, Limit: 10000",
"usage": {
"api_requests_used": 10000,
"api_requests_limit": 10000,
"api_requests_remaining": 0
}
}
C’est intentionnel : l’épuisement du quota ne doit pas ressembler à une panne serveur ni bloquer votre pipeline avec une exception. Vérifiez usage.api_requests_remaining (ainsi que le message) au lieu de vous fier au code de statut. Si vous laissez passer en cas de 200, un quota épuisé laisserait silencieusement du contenu passer sans vérification — prévoyez donc explicitement une branche sur ces champs.
Comment lire une réponse réussie ?
Un 200 de /api/v2/check contient toujours has_violations et cached ; le reste est facultatif :
| Champ | Type | Signification |
|---|---|---|
has_violations |
boolean | Vrai si au moins une vérification activée a signalé le contenu |
cached |
boolean | Vrai si la réponse provient d’un cache récent pour une requête identique |
message |
string | Présent en cas d’épuisement du quota (et d’avis similaires ne constituant pas des erreurs) |
request_id |
string | Renvoyé si vous en avez fourni un |
processing_time_ms |
number | Présent lorsque la mesure du temps est activée pour le projet |
usage |
object | api_requests_used, api_requests_limit, api_requests_remaining |
results |
object | Détails par vérification (spamfinder, sentiment, images, …) et indicateur de premier niveau hits |
Basez la décision globale sur has_violations, puis consultez results.<check>.hit pour savoir quelle vérification s’est déclenchée.
Quel est l’effet du cache sur les réponses ?
Les requêtes identiques pour un même projet sont dédupliquées : une répétition renvoie cached: true avec le même résultat. Le cache est propre à chaque projet. Notez qu’une requête servie depuis le cache compte quand même dans votre quota de requêtes API — cela économise du temps de traitement, pas du quota.
Vous pouvez joindre un request_id à une requête pour votre propre corrélation ; il est renvoyé tel quel dans la réponse.
Un client minimal et correct
async function check(content, settings) {
const response = await fetch('https://api.discuse.com/api/v2/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.DISCUSE_API_KEY
},
body: JSON.stringify({ content, settings })
});
// 400: bad request — fix it, don't retry. 5xx: transient/auth/rate-limit — retry with backoff.
if (response.status === 400) {
throw new Error('Invalid request: ' + (await response.text()));
}
if (!response.ok) {
throw new Error(`Discuse error ${response.status}`); // retry upstream with backoff
}
const data = await response.json();
// Quota exhausted is a 200 — never treat it as "checked and clean".
if (data.usage && data.usage.api_requests_remaining === 0 && data.message) {
throw new Error('Quota exhausted: ' + data.message);
}
return data; // inspect data.has_violations and data.results
}
Articles connexes
- Authentification et clés API — clés, en-tête
X-API-Keyet limites de débit - Guide de démarrage rapide — votre première requête en quelques minutes
- Analyse de texte — l’objet
resultsen détail