> ## Documentation Index
> Fetch the complete documentation index at: https://docs.querying.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Erreurs

> L'enveloppe d'erreur, tous les codes renvoyés par l'API et ce qui mérite une nouvelle tentative.

Les échecs partagent une même enveloppe :

```json theme={null}
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [{ "field": "payload.prompt", "message": "payload.prompt or payload.query is required" }],
    "timestamp": "2026-07-09T04:12:00.000Z"
  }
}
```

`code` est stable et fiable pour brancher. `message` est destiné aux humains et peut changer. `details` est présent
quand nous pouvons nommer le champ fautif.

## Codes

| Code | Statut | Signification | Relancer ? |
| - | - | - | - |
| `MISSING_API_KEY` | 401 | Jeton bearer absent ou erroné. | Non : corrigez la clé |
| `VALIDATION_ERROR` | 400 | Corps mal formé, `taskType` inconnu, ou ni `payload.prompt` ni `payload.query`. | Non : corrigez la requête |
| `REGION_UNSUPPORTED` | 422 | Ce moteur ne pourra jamais servir le `country` demandé. | Non : choisissez un autre moteur ou une autre région |
| `REGION_UNAVAILABLE` | 422 | Aucune capacité pour le `country` demandé sur ce moteur pour le moment. | Plus tard, quand la capacité revient |
| `RESOURCE_ALREADY_EXISTS` | 409 | `idempotencyKey` en double sur l'endpoint unitaire. | Non : la tâche existe déjà |
| `PAYLOAD_TOO_LARGE` | 413 | Le corps du lot dépasse 8 Mo. | Non : envoyez des morceaux plus petits |
| `RESOURCE_NOT_FOUND` | 404 | Id de tâche inconnu, ou la tâche a dépassé la fenêtre publique de polling de 24 heures. | Non |
| `ENQUEUE_ERROR` | — | Échec d'un élément dans un lot (p. ex. un incident de base de données sur une voie). Apparaît dans `results[].error`, jamais comme statut HTTP. | Oui |

<Note>
  `400` concerne une requête que nous ne pouvons ni analyser ni comprendre. `422` est réservé à une requête
  parfaitement formée que nous ne pouvons pas servir pour la région demandée. Brancher sur `error.code` est plus
  durable que sur le statut.
</Note>

## Refus liés à la région

Les deux codes de région sont décidés **avant** la mise en file : vous le savez immédiatement, au lieu de voir une
tâche épuiser toutes ses tentatives et échouer avec une erreur qui ne montre que le symptôme.

`REGION_UNSUPPORTED` est permanent : ce moteur ne peut pas servir le pays demandé.

```json theme={null}
{
  "success": false,
  "error": {
    "code": "REGION_UNSUPPORTED",
    "message": "CHATGPT cannot be served for country='CN': no proxy vendor has exit supply in CN. This is a permanent capability gap, not a transient one — retrying will not help. GOOGLE and AIMODE are unaffected by exit-IP limits and remain available for this country.",
    "details": { "taskType": "CHATGPT", "country": "CN", "cause": "no_proxy_route", "retryable": false },
    "timestamp": "2026-07-09T04:12:00.000Z"
  }
}
```

Consultez [le tableau des combinaisons non desservies](/fr/engines/capacity).

`REGION_UNAVAILABLE` est transitoire : la route existe mais rien ne peut la servir pour l'instant. Interrogez
[`GET /capacity`](/fr/api-reference/capacity) pour voir ce que chaque région peut servir actuellement.

## Les échecs de lot sont par élément

Un lot bien formé renvoie toujours `200`, même si toutes ses tâches échouent. Le statut HTTP décrit la *requête* ;
`results[].success` décrit chaque *tâche*.

```json theme={null}
{
  "success": true,
  "summary": { "total": 3, "succeeded": 2, "failed": 1 },
  "results": [
    { "success": true,  "index": 0, "task": { "...": "..." } },
    { "success": false, "index": 1, "error": { "code": "REGION_UNAVAILABLE", "message": "..." } },
    { "success": true,  "index": 2, "task": { "...": "..." } }
  ]
}
```

Seule une requête mal formée dans son ensemble (pas du JSON, pas un tableau, vide, plus de 500 éléments, plus de 8 Mo,
ou non autorisée) produit un 4xx pour le lot lui-même.

<Note>
  Un élément de lot peut échouer avec `REGION_UNAVAILABLE` ou `ENQUEUE_ERROR`, qui ne figurent ni l'un ni l'autre dans
  l'enum des erreurs par élément du contrat de tâches asynchrones que cette API implémente. Ce sont des ajouts, pas des
  remplacements : `VALIDATION_ERROR` et `RESOURCE_ALREADY_EXISTS` sont inchangés.
</Note>

## Échecs au niveau de la tâche

Une tâche qui échoue *après* sa mise en file ne produit aucune erreur HTTP. Vous l'apprenez par le statut final :

```json theme={null}
{
  "success": true,
  "task": { "id": "8f2c1e40-...", "status": "FAILED", "...": "..." },
  "credits": { "creditsToCharge": 0, "creditsCharged": 0 },
  "error": "ENGINE_TIMEOUT: The engine did not answer before the task deadline."
}
```

Notez la différence de forme : ce `error` de premier niveau est une **chaîne**, pas l'objet
`{code, message, timestamp}` des erreurs de requête. Il commence par un code suivi d'une phrase fixe propre à ce code ;
basez donc votre logique sur le code : `ENGINE_TIMEOUT`, `ENGINE_NO_RESULT`, `ENGINE_FAILED`, ou `NO_IP_AVAILABLE` et
`NO_ACCOUNT_AVAILABLE` quand aucune capacité ne s'est libérée à temps (réessayer plus tard fonctionne généralement).
`BAD_PAYLOAD` et `PAGE_UNAVAILABLE` (une page Naver impossible à lire de façon anonyme) gardent un message qui indique
quoi changer. La même tâche livre un webhook avec `task.status === "FAILED"`.
