Référence API

Tâches asynchrones

Les traitements d'image, de vidéo et de musique partagent un même cycle de vie durable : soumettre une fois, enregistrer task_id, observer un état final, puis récupérer le résultat. Construisez un seul exécuteur de tâches et choisissez seulement la famille d'endpoints selon le modèle.

#Un seul cycle de vie pour tous les modèles asynchrones

  1. 1

    Soumettre une seule fois

    Utilisez une Idempotency-Key unique et enregistrez la réponse immédiatement.

    POST /v1/{capability}
  2. 2

    Enregistrer task_id

    Stockez-le avant que le worker n'acquitte le traitement.

    task_id
  3. 3

    Interroger ou recevoir un webhook

    Comparez status sans tenir compte de la casse et arrêtez-vous à un état final.

    GET /{task_id}
  4. 4

    Récupérer et enregistrer le résultat

    Appelez /content après un succès et stockez l'URL de plateforme renvoyée.

    GET /{task_id}/content

#Familles d'endpoints

CapacitéSoumettreInterrogerContenu
Image/v1/images/tasks/v1/images/tasks/{task_id}/v1/images/tasks/{task_id}/content
Vidéo/v1/videos/v1/videos/{task_id}/v1/videos/{task_id}/content
Musique/v1/music/generations/v1/music/tasks/{task_id}/v1/music/tasks/{task_id}/content

#Valeurs de statut

Un seul cycle de vie, deux vocabulaires d'échange. Les tâches d'image, de musique et 3D utilisent les termes de tâche d'OpenAI ; les vidéos et toutes les charges utiles de webhook utilisent les termes vidéo d'OpenAI. Une vérification de statut écrite pour une famille ne correspondra jamais, sans rien signaler, dans l'autre — ce tableau fait la correspondance.

Cycle de vieImage · musique · 3DVidéo · webhookFinalSignification
NOT_STARTprocessingqueuednonAcceptée par la passerelle, pas encore transmise à un canal.
SUBMITTEDqueuedqueuednonEnvoyée en amont et prise en compte par le fournisseur.
QUEUEDqueuedqueuednonEn attente dans la file du fournisseur.
IN_PROGRESSprocessingin_progressnonRendu en cours. progress contient un pourcentage sous forme de chaîne, par exemple "60%".
SUCCESSsucceededcompletedouiTerminée. Récupérez le résultat depuis /content.
FAILUREfailedfailedouiÉchec définitif. fail_reason en donne la raison ; le quota réservé est remboursé.
UNKNOWNunknownunknownnonLe fournisseur ne renvoie plus d'état que la passerelle sait interpréter. Continuez d'interroger avec une échéance, puis faites le rapprochement — ne le traitez ni comme un succès ni comme un échec.

Testez l'ensemble des états finaux, jamais « n'est plus en cours »

Considérez succeeded / completed et failed comme les seuls points d'arrêt, et tout le reste — y compris un terme absent de ce tableau — comme encore en cours. De nouveaux états intermédiaires peuvent apparaître ; de nouveaux états finaux constitueraient un changement incompatible et n'apparaîtront pas.

UNKNOWN n'est pas un échec

Une tâche peut rester en UNKNOWN lorsque le fournisseur cesse de renvoyer un état que la passerelle sait interpréter. Interrogez-la avec une échéance et faites remonter le cas à une personne ou à un processus de rapprochement — la traiter comme un échec fait payer deux fois la nouvelle tentative, la traiter comme un succès livre un résultat vide.

#Boucle d'interrogation sûre

Arrêtez-vous sur les termes finaux de la famille que vous interrogez, gardez une échéance en temps réel pour tout le reste, et espacez les tentatives pour qu'une tâche bloquée ne se transforme pas en boucle effrénée.

poll.py
import time, requests

# The two vocabularies. Pick the one that matches the endpoint you poll.
TASK_DONE, TASK_FAILED = {"succeeded"}, {"failed"}      # images / music / 3D
VIDEO_DONE, VIDEO_FAILED = {"completed"}, {"failed"}    # videos + webhooks
DEADLINE_SECONDS = 15 * 60

def wait_for_image_task(task_id, api_key):
    started = time.monotonic()
    delay = 2
    while True:
        response = requests.get(
            f"https://www.aisplice.store/v1/images/tasks/{task_id}",
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()
        status = task.get("status", "")

        if status in TASK_DONE:
            return task
        if status in TASK_FAILED:
            raise RuntimeError((task.get("error") or {}).get("message", "task failed"))

        # queued / processing / unknown all mean "not finished". Wait — but
        # never forever: hand an overdue task to reconciliation.
        if time.monotonic() - started > DEADLINE_SECONDS:
            raise TimeoutError(f"task {task_id} still {status} after the deadline")

        time.sleep(delay)
        delay = min(delay * 1.5, 15)

Reprendre après un redémarrage

Enregistrez task_id, la famille d'endpoints, le modèle, l'heure de création et votre propre identifiant métier. Un worker redémarré peut reprendre l'interrogation sans soumettre ni payer une seconde tâche.

#Conservation des résultats

Ne récupérez /content qu'après un succès. Enregistrez l'URL de plateforme renvoyée dans votre enregistrement métier, et téléchargez une copie privée si vos exigences de conservation imposent un stockage indépendant.

Toujours bloqué ?

Envoyez-nous l'ID de requête ou le message d'erreur, et nous examinerons le problème.