Erreurs et limites
Codes d’erreur de GetVibe API : 401 (clé), 402 (solde), 403 (IP), 429 (limite de débit). Comment gérer les erreurs et réessayer avec un backoff exponentiel.
Les erreurs produites par GetVibe sur /v1/* contiennent une enveloppe JSON avec error.message, error.type et error.code. Ne vous fiez pas au texte du message ni aux en-têtes des services tiers comme s’il s’agissait d’un contrat.
Format des erreurs
{
"error": {
"message": "insufficient balance",
"type": "insufficient_quota",
"code": 402,
"request_id": "8d4b6b3a-..."
}
}Codes de réponse
| Paramètre | Type | Description |
|---|---|---|
401 | authentication_error / 401 | Clé manquante ou mal formée, ou clé désactivée. Ne réessayez pas tant que les identifiants n’ont pas été corrigés. |
402 | insufficient_quota / 402 | Aucun solde ou aucune limite disponible : attendre ne résoudra pas le problème. Une réponse 402 ne contient jamais Retry-After et ne doit pas faire l’objet d’une nouvelle tentative : approvisionnez votre compte ou attendez la réinitialisation de la période d’abonnement. |
403 | permission_error or policy type / 403 | L’adresse IP, le modèle ou la stratégie n’autorise pas la requête. Ne réessayez pas sans modifier la requête ou les paramètres. |
429 | rate_limit_exceeded, inflight_client_cap or rate_limit_error / 429 | Votre limite de débit, votre limite de concurrence, une réservation de solde brièvement retenue par vos propres requêtes concurrentes (cause reserved_in_flight), ou une limite du fournisseur. Réessayez uniquement après Retry-After ; un 429 ne signifie jamais que votre solde est épuisé. |
410 | media_endpoint_retired / media_endpoint_retired | Uniquement /v1/images/edits, /v1/video/generations et /v1/videos (retirés). Ne réessayez pas ; utilisez /api/media/generate. /v1/images/generations est disponible. |
413 | invalid_request_error / 413 | API Files uniquement : le fichier dépasse 50 MiB. Réduisez le fichier, puis créez une nouvelle requête. |
503 | overloaded / 503 | Surcharge globale de l’edge. Réessayez après Retry-After: 2. Les autres erreurs 503 peuvent ne pas être réessayables sans modifier le modèle ou la requête. |
Erreurs de requête (400, 413, 422) : codes et solutions
Chaque erreur de requête contient un error.code stable provenant du tableau ci-dessous, un error.param indiquant le champ concerné (null lorsque le modèle n’en a pas indiqué), ainsi qu’un lien vers la ligne correspondante à la fin de error.message — Codex et les autres CLI n’affichent que le message ; le lien y est donc inclus.
| error.code | error.param | Que faire |
|---|---|---|
unsupported_parameter | nom du champ | Le modèle ou le canal sélectionné n’accepte pas ce paramètre. Supprimez-le de la requête (dans Codex/les IDE, de la configuration), puis réessayez. |
invalid_parameter_value | nom du champ | Le paramètre est présent, mais sa valeur n’est pas autorisée pour ce modèle : par exemple, une valeur de temperature autre que 1 avec le raisonnement activé, une valeur de max_tokens supérieure au maximum ou une valeur d’effort « none » lorsque le raisonnement ne peut pas être désactivé. Corrigez la valeur comme indiqué dans le message. |
missing_parameter | nom du champ | Un champ obligatoire est manquant ou vide. Ajoutez-le. |
invalid_tool_schema | tools[].function.* | Une définition d’outil a été rejetée : les noms peuvent uniquement utiliser des lettres latines, des chiffres, « _ » et « - » ; les paramètres doivent être un schéma JSON dont la racine est de type « object ». Vous pouvez également choisir une autre variante du modèle. |
tool_choice_unsupported | tool_choice | Le modèle ne prend pas en charge un choix d’outil forcé. Envoyez tool_choice « auto » ou « none ». |
invalid_tool_history | messages / input | L’historique contient un appel d’outil sans résultat. Ajoutez le résultat avec le même id, ou supprimez l’appel et son résultat lorsque vous réduisez l’historique. |
invalid_image | — | L’image n’a pas pu être lue. Envoyez un fichier PNG, JPEG, WebP ou GIF complet (BMP, TIFF, AVIF et SVG ne sont pas acceptés). |
unsupported_input_modality | — | Le modèle n’accepte pas ce type de pièce jointe (PDF, audio, vidéo, images). Supprimez-la ou choisissez un modèle dont l’entrée de catalogue répertorie ce type d’entrée. |
conversation_state_unreadable | — | Le raisonnement présent dans l’historique a été créé par un autre canal. La requête est valide ; réessayez et, si l’erreur se répète, démarrez une nouvelle conversation. |
invalid_json | — | Le corps de la requête n’est pas au format JSON ou est arrivé tronqué. Pour les conversations très longues contenant des images, démarrez une nouvelle conversation ou compactez l’historique. |
request_too_large | — | La requête est trop volumineuse. Réduisez les pièces jointes ou l’historique. |
request_rejected_by_channel | — | Le canal du modèle a refusé la requête sans en indiquer la raison ; la requête elle-même est très probablement valide. Réessayez ; si le refus se répète, choisissez une autre variante du modèle (le suffixe après les deux-points) ou le modèle sans suffixe. Si cela ne résout pas le problème, contactez le support en indiquant le request_id. |
model_not_available_on_route | — | La route n’est pas configurée pour ce modèle. Choisissez un autre modèle ou une autre variante. |
context_length_exceeded | messages / input / prompt | La requête ne tient pas dans la fenêtre de contexte. Compactez l’historique (dans Codex : /compact) ou choisissez un modèle doté d’une fenêtre plus grande. |
content_moderation | — | La requête ou la réponse a été bloquée par le filtre de contenu du fournisseur. Reformulez-la ou choisissez un autre modèle. |
invalid_request | — | La cause n’a pas été identifiée. Vérifiez la requête par rapport à la référence de l’API ; si elle est correcte, contactez le support en indiquant le request_id de la réponse. |
En-têtes de réponse
| Paramètre | Type | Description |
|---|---|---|
x-pv-cost-rub | string | Estimation indicative du coût en roubles. Dans les flux, x-pv-cost-rub est disponible lorsque l’estimation de l’entrée est connue ; pv_cost_rub dans l’événement d’utilisation final nécessite x-pv-cost: 1. L’historique d’utilisation contient le débit réel. |
x-pv-generation-id | string | Identifiant de l’enregistrement de l’historique de l’utilisation (GET /v1/generations/{id}). Renvoyé uniquement pour les requêtes chat/completions sans streaming. |
x-pv-dropped-params | string | Paramètres de requête séparés par des virgules que la route sélectionnée n’accepte pas et qui n’ont donc pas été envoyés au modèle (par exemple temperature,top_p). Présents uniquement lorsqu’un élément a effectivement été retenu, aussi bien dans les réponses que dans les erreurs. Nous ne supprimons jamais silencieusement un paramètre : en l’absence d’en-tête, tout ce que vous avez envoyé est parvenu au modèle sans modification. |
Retry-After | integer | Nombre de secondes d'attente. Le système en définit la valeur pour le débit 429, la concurrence 429 (5), la surcharge globale 503 (2) et certains 402 transitoires. Cette valeur n'est pas supposée pour tous les 429/503. |
Erreurs avant et après le début de la réponse
Un flux lent (stream: true) reçoit 200 et : pv-keepalive commentaires après 5 secondes de silence afin que la connexion ne semble pas interrompue ; une longue requête sans flux reçoit 200 et des espaces après son premier jeton. À partir de là, le statut ne peut plus changer et une erreur arrive dans le corps. Si votre client bascule vers un autre fournisseur en cas d’erreur HTTP, envoyez x-pv-honest-errors: 1 (ou demandez au support de l’activer pour le compte) : il n’y a alors aucun keepalive ni aucun 200 anticipé avant le premier octet de la réponse, et chaque échec correspond à un statut HTTP ordinaire avec un corps JSON. Le coût est une socket silencieuse jusqu’au premier jeton ; votre délai d’expiration des en-têtes doit le couvrir.
Une erreur survenant après le début de la réponse constitue un événement terminal unique : pour le chat event: error avec {"error":{message,type,code,status},"choices":[{"finish_reason":"error"}]}, suivi de data: [DONE] ; pour /v1/responses event: response.failed contenant le même error ; pour /v1/messages, le event: error d’Anthropic. code indique la cause technique et status correspond au statut HTTP qu’aurait eu l’erreur avant le début de la réponse.
stream: true), x-pv-generation-id n’est pas renvoyé, car la facturation se termine après la fin du streaming. Consultez l’historique des requêtes via GET /v1/generations.Limites de débit et de concurrence
Les deux limites dépendent du solde actuel du compte et s’appliquent à l’ensemble de ses clés API. Le palier est recalculé automatiquement : rechargez votre compte et la limite augmente ; si le solde passe sous un seuil, le palier diminue. Il n’y a pas de limite de tokens par minute (TPM).
| Solde à partir de | Requêtes par minute (RPM) | Requêtes simultanées |
|---|---|---|
| 0 $ | 300 | 10 |
| 1 $ | 1 100 | 50 |
| 2 $ | 6 600 | 300 |
| 4 $ | 19 800 | 900 |
| 12 $ | 44 000 | 2 000 |
| Paramètre | Type | Description |
|---|---|---|
429 rate_limit_exceeded | RPM | Le compte a envoyé autant de requêtes au cours des 60 dernières secondes (fenêtre glissante) que son palier l’autorise. Retry-After indique le nombre de secondes avant qu’un emplacement ne se libère dans la fenêtre (au moins 1) ; x-ratelimit-limit-requests correspond à votre limite actuelle de RPM. Corps : error.cause = key_rate_limited, error.details = { enforced_by: "getvibe", limit, unit: "requests_per_minute", retry_after_seconds }. |
429 inflight_client_cap | concurrency | Le nombre de requêtes déjà en cours a atteint la limite autorisée par le palier. Une requête occupe son emplacement jusqu’à sa fin ; un flux l’occupe jusqu’à son dernier événement. Retry-After: 5. Corps : error.cause = account_concurrency_limited, error.details = { enforced_by: "getvibe", limit, unit: "parallel_requests", retry_after_seconds: 5 }. |
Personal limit | RPM | Si le compte dispose d’une limite de requêtes personnalisée, celle-ci peut uniquement réduire le nombre de RPM du palier, jamais l’augmenter. |
503 overloaded | service | Il ne s’agit pas de votre limite, mais d’une protection du service : Retry-After: 2 correspond au plafond global pour l’ensemble des comptes, tandis que Retry-After: 1 signifie qu’un serveur est occupé. Réessayez après le délai indiqué. |
429 from a provider | upstream | error.cause = supplier_rate_limited signifie que le fournisseur du modèle a limité la requête et que votre propre limite n’est pas épuisée ; channel_rate_limited correspond au plafond partagé d’un canal de fournisseur (Retry-After: 10, rien n’a été envoyé). |
Nouvelle tentative des requêtes
Pour une réponse pouvant faire l'objet d'une nouvelle tentative, utilisez d'abord Retry-After, s'il est présent. Sans cet en-tête, ne considérez aucun 429 ou 503 comme automatiquement réessayable : vérifiez le statut HTTP et le error.type public, corrigez la cause non réessayable et utilisez un backoff limité uniquement en cas d'erreur transitoire.
import time, requests
def call_with_retry(url, headers, payload, max_retries=5):
for attempt in range(max_retries):
r = requests.post(url, headers=headers, json=payload)
if r.status_code == 429:
# honor Retry-After, otherwise exponential backoff
wait = int(r.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
return r
return r