PopNowDocs API
Référence
Contenu principal

Erreurs

Chaque code métier, ce qu’il signifie et quelles erreurs valent la peine d’être réessayées.

Quand un appel échoue, la réponse vous donne un nombre (code) qui indique le type de problème et une phrase (msg) destinée à un humain. Basez votre logique sur le nombre ; affichez ou journalisez la phrase.

L’enveloppe

{ "code": 40201, "msg": "Insufficient balance", "request_id": "req_…" }
  • code est un code métier. 200 signifie succès ; toutes les autres valeurs sont listées ci-dessous.
  • En cas d’échec, il n’y a pas de champ data, sauf pour quelques erreurs de la bibliothèque de ressources qui ajoutent data.reason.
  • Le statut HTTP est aussi renseigné (40201 arrive avec HTTP 402). Appuyez-vous sur l’un des deux, sans les mélanger — nous recommandons code, plus précis.
  • request_id figure aussi dans l’en-tête X-Request-Id. Indiquez-le quand vous contactez le support.

Si une réponse n’est pas du JSON du tout — une page HTML ou texte venue du réseau intermédiaire —, traitez-la selon le statut HTTP et journalisez le début du corps.

Langue des messages d’erreur

msg et l’errorMessage d’une tâche en échec sont en anglais par défaut. Envoyez Accept-Language avec en, ja, ko, de, fr, es, pt-BR, ru, it ou pl, ou réglez la langue des erreurs API dans la console, pour les recevoir dans cette langue ; les autres langues reviennent à l’anglais. Les réponses d’erreur portent Content-Language. Les codes ne changent jamais avec la langue — une raison de plus de ne jamais analyser msg.

Quand un modèle donne une raison précise à son échec (par exemple une image de référence illisible), errorMessage la transmet en anglais, sans les détails internes.

Codes généraux

codeHTTPSignificationRéessayer ?
200200 / 202Succès—
400400La requête ou son input est invalide ; msg précise le problèmeNon — corrigez
40003400Un envoi ne correspond pas à son ticket (taille, type ou contenu)Non — nouveau ticket, nouvel envoi
40004400Requête valide, mais le modèle ne peut pas servir cette combinaison de réglages pour l’instantNon — modifiez le réglage cité dans msg
401401Clé absente, inconnue ou révoquée (détails)Non
403403Non autorisé (voir Autorisations)Non
404404N’existe pas, ou appartient à une autre cléNon
409409Conflit avec l’état actuel (quand réessayer)Parfois
40901409Un devis a expiré ou le prix a changéRedemandez un devis
413413Corps de requête trop volumineuxNon — envoyez les médias au lieu de les intégrer
429429Trop de requêtesOui — après Retry-After
500500Un problème de notre côtéOui — avec un délai croissant
503503Un service d’appui est brièvement indisponibleOui — après Retry-After

Solde et plafonds

codeHTTPSignificationQue faire
40201402Pas assez de crédits pour la réservation de cette tâcheAchetez des crédits, puis renvoyez
40202402Un plafond de dépense de la clé est atteintRelevez-le dans la console API ou attendez sa remise à zéro

Autorisations

codeHTTPSignificationQue faire
40301403Cette clé ne peut pas appeler ce modèleAjoutez le modèle à la liste autorisée de la clé
40302403La requête vient d’une adresse hors de la liste d’IP autoriséesAjoutez l’adresse ou retirez la restriction
40303403Le service n’est pas proposé dans cette régionImpossible à contourner
40310403L’adresse e-mail du compte n’est pas encore vérifiéeOuvrez le lien de l’e-mail d’inscription ; la clé fonctionne dès la vérification

Un simple 403 avec une clé valide signifie que le compte ne peut pas utiliser l’API pour le moment ; contactez le support avec le request_id.

Disponibilité des modèles

codeHTTPSignificationRéessayer ?
50301503Le modèle ne peut pas prendre de tâches en ce momentOui, plus tard — ou choisissez un autre modèle
40004400Le modèle fonctionne, mais pas avec ces réglagesNon — changez le réglage

Aucun des deux ne crée de tâche ni ne réserve de crédits.

Codes d’échec des tâches

Une tâche acceptée puis en échec a state: "failed" et l’une de ces valeurs dans errorCode. La liste est fermée : traitez toute autre valeur comme upstream_failed.

errorCodeSignificationRéessayer ?
invalid_requestLe modèle n’a pas accepté les paramètresNon — corrigez-les
unsupported_combinationCette combinaison de réglages n’est pas prise en charge pour l’instantNon — changez un réglage
content_rejectedLe modèle a refusé ce contenuNon — modifiez le prompt ou la référence
invalid_assetUn fichier de référence est illisible ou n’est plus disponibleRenvoyez-le et créez une nouvelle tâche
rate_limitedLe service de génération était saturéOui, avec un délai croissant
upstream_unavailableLa génération est temporairement indisponibleOui, un peu plus tard
generation_failedLa génération a tourné mais n’a rien produitPeut-être — la même entrée échoue souvent de la même façon
timeoutLa tâche a manqué de tempsPeut-être — essayez une sortie plus courte ou moins définie
upstream_failedTout le resteOui, avec un délai croissant

Une tâche en échec libère sa réservation et ne coûte donc rien (quelques modèles facturent les refus de contenu et le précisent sur leur page). errorMessage explique la raison en toutes lettres ; basez votre logique uniquement sur errorCode.

Quand un 409 vaut un nouvel essai

CasRéessayer ?
Deux requêtes avec le même Idempotency-Key sont arrivées ensembleOui, avec la même clé, après une courte pause
L’Idempotency-Key a servi à une autre requête ou à une autre cléNon
Un envoi ou un résultat est encore en traitementOui, après quelques secondes
jobs/retry sur une tâche pas encore terminéeOui, une fois qu’elle est finale
jobs/retry sur une tâche réussieNon — créez une nouvelle tâche
Un ticket d’envoi ou un fichier envoyé a expiréNon — renvoyez le fichier

Écrire le nouvel essai

Ne réessayez que ce qui peut réussir la deuxième fois, attendez Retry-After quand il est fourni, et sinon augmentez le délai de façon exponentielle :

JavaScript
const RETRYABLE = new Set([429, 500, 503, 50301]);

async function call(path, init, attempts = 4) {
  for (let i = 0; i < attempts; i++) {
    const res = await fetch(`https://api.popnow.ai/api/v1${path}`, init);
    if (!res.headers.get('content-type')?.includes('json')) {
      throw new Error(`HTTP ${res.status}: ${(await res.text()).slice(0, 200)}`);
    }
    const body = await res.json();
    if (body.code === 200) return body.data;
    if (!RETRYABLE.has(body.code)) throw new Error(`${body.code} ${body.msg} (${body.request_id})`);
    const wait = Number(res.headers.get('retry-after')) * 1000 || 2 ** i * 1000 + Math.random() * 500;
    await new Promise((r) => setTimeout(r, wait));
  }
  throw new Error('out of retries');
}
Python
import random, time, requests

RETRYABLE = {429, 500, 503, 50301}

def call(method, path, attempts=4, **kwargs):
    for i in range(attempts):
        res = requests.request(method, f"https://api.popnow.ai/api/v1{path}", timeout=60, **kwargs)
        try:
            body = res.json()
        except ValueError:
            raise RuntimeError(f"HTTP {res.status_code}: {res.text[:200]}")
        if body["code"] == 200:
            return body["data"]
        if body["code"] not in RETRYABLE:
            raise RuntimeError(f'{body["code"]} {body["msg"]} ({body.get("request_id")})')
        retry_after = res.headers.get("retry-after")
        time.sleep(float(retry_after) if retry_after else 2**i + random.random() / 2)
    raise RuntimeError("out of retries")

Quand vous réessayez createTask, envoyez toujours le même Idempotency-Key, pour qu’une requête qui avait en fait réussi ne soit pas exécutée ni facturée deux fois.

Diagnostic

  1. Notez le request_id et le code.
  2. Retrouvez la tâche dans les journaux de la console API, par identifiant de tâche ou request_id.
  3. Toujours bloqué ? Contactez le support avec le request_id, l’heure (UTC) et le code. N’envoyez jamais votre clé API.

Sur cette page