Erreurs et nouvelles tentatives
Codes métier, statuts HTTP, stratégie de relance et facturation.
Toutes les réponses JSON utilisent l’enveloppe {code,msg,data,request_id}. Branchez votre logique sur code, jamais sur msg, et transmettez request_id au support.
{
"code": 200,
"msg": "success",
"data": {},
"request_id": "req_…"
}Langue des messages d’erreur
Les textes d’erreur destinés aux humains peuvent être renvoyés dans la langue de votre choix. Trois champs sont concernés : msg dans la réponse, errorMessage d’une tâche en échec (dans recordInfo comme dans les livraisons webhook) et error.message dans les objets d’erreur des API compatibles, qu’elles suivent le format OpenAI, Anthropic ou Google Gemini. La langue par défaut est l’anglais. Codes de langue pris en charge : en, zh-Hant, ja, ko, de, fr, es, pt-BR, ru.
Seul le texte lisible change. Les valeurs de code et errorCode, de type et code dans la couche compatible OpenAI, de code et status dans la couche compatible Gemini, ainsi que tous les noms de champs, restent identiques d’une langue à l’autre. Branchez votre logique sur les codes, jamais sur le texte, et consignez code et request_id dans vos journaux et alertes. L’en-tête de réponse Content-Language indique la langue réellement utilisée. Exemple : pour un même 40201 (solde insuffisant), msg vaut « Insufficient balance » par défaut ; avec Accept-Language: ja, msg est en japonais et code reste 40201.
La langue est déterminée dans cet ordre :
- En-tête Accept-Language : s’applique à cette seule requête. La pondération HTTP standard est respectée : la langue reconnue ayant la valeur q la plus élevée est retenue. Les variantes régionales sont ramenées à leur langue : de-DE devient de, pt-PT devient pt-BR, zh-TW, zh-HK et zh-Hant deviennent zh-Hant. Le chinois n’est proposé qu’en caractères traditionnels ; zh-CN et zh-Hans ne correspondent donc à aucune langue et le candidat suivant est examiné. * signifie « aucune préférence ».
- Réglage du compte : dans la console, « Réglages → Langue des erreurs de l’API ». Il s’applique à toute requête envoyée avec une clé API de ce compte qui ne porte pas d’en-tête Accept-Language reconnaissable. La plupart des SDK côté serveur et curl n’envoient pas cet en-tête par défaut ; c’est donc, en pratique, la méthode la plus courante. Les livraisons webhook n’ont pas d’en-tête de requête et suivent toujours le réglage du compte.
- À défaut, l’anglais est utilisé.
# Default: no Accept-Language, no account setting
HTTP/1.1 402 Payment Required
Content-Language: en
{ "code": 40201, "msg": "Insufficient balance", "request_id": "req_…" }
# The same request with one extra header
curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
-H "Accept-Language: ja" \
--data "$TASK_PAYLOAD"
HTTP/1.1 402 Payment Required
Content-Language: ja
{ "code": 40201, "msg": "残高が不足しています", "request_id": "req_…" }Erreurs à ne pas retenter
400, 401, 403, 404, 40201, 40202 et 40301 à 40303 ne changeront pas avant correction de l’entrée, des identifiants, des droits, du solde ou du plafond. Un 413 indique un corps trop volumineux : ne le renvoyez pas inchangé, réduisez-le ou utilisez le téléversement de média.
Erreurs retentables
Pour 429, respectez Retry-After. Pour les HTTP 500/503 et les codes métier 500/50301, utilisez un backoff exponentiel avec jitter. Un 409 dépend de l’opération : ne retentez que media pending ou le rare conflit concurrent createTask avec le même Idempotency-Key et le même payload. Un conflit de clé avec un autre payload n’est pas retentable.
Lors d’une erreur réseau sur createTask, réutilisez le même Idempotency-Key. La même clé avec un autre payload renvoie 409.
Facturation
Une requête rejetée avant la création n’est pas facturée. Après création, failed, expired et les anciens enregistrements canceled libèrent toute la réserve. Une nouvelle tâche acceptée ne peut pas être annulée ; seul succeeded est réglé selon l’usage réel.
Consultez le contrat OpenAPI 3.1 pour la définition complète des champs.

