Thème
Langue

Webhooks et cycle de vie des tâches multimédias

Enregistrez un mediaWebhookUrl, recevez un POST lorsqu’une tâche est terminée, interrogez GET /api/media/jobs/{id}, gérez les codes d’erreur et comprenez les limites de facturation et d’idempotence.

Guide opérationnel des tâches multimédias asynchrones : enregistrement des webhooks, statuts, interrogation périodique, codes d’erreur, frais et limites d’idempotence, strictement selon l’implémentation actuelle du code.

Cycle de vie d’une tâche

  1. POST /api/media/generate — en cas de succès, 202 et { ok: true, jobId, status: "processing" }. L’API ne comporte pas de statuts distincts queued / running : jusqu’à la fin du job, le client voit processing.
  2. L’amont peut passer par des étapes internes (waiting, generating) qui ne sont pas reflétées dans l’API publique ; pendant l’interrogation, la tâche reste processing.
  3. États du terminal : success (contient resultUrls, facturé en cas de succès) ou fail (aucun frais).
  4. La complétion est enregistrée une seule fois : via le callback en amont ou lors d’une interrogation différée dans GET /api/media/jobs/{id}.

Interrogation : GET /api/media/jobs/{id}

GEThttps://getvibeapi.com/api/media/jobs/{id}
ParamètreTypeDescription
statusstringsubmitting | processing | success | fail. submitting + media_submission_uncertain is non-terminal; within about 10–15 minutes such a submission is closed as fail (media_submission_not_started) without a charge — create a new task.
resultUrlsstring[]URL signées /api/media/file/{id}/{idx}?sig=… (sans clé API).
priceRubnumberMontant des frais en USD (0 en cas d’échec ou avant la fin).
failMsgstring | nullMessage de sécurité en cas d'échec ou de media_submission_uncertain non terminal.
errorCodestring | nullCode d’erreur (media_generation_failed) ou non-terminal media_submission_uncertain.
retryGuidancestring | nullSur media_submission_uncertain : une instruction sûre pour interroger ultérieurement le même jobId et ne pas créer automatiquement de doublon.
# 2. poll the job until it is ready
curl https://getvibeapi.com/api/media/jobs/JOB_ID \
  -H "Authorization: Bearer $GETVIBE_API_KEY"
# → {"status":"success","resultUrls":["https://..."],"priceRub":...}
Intervalle d’interrogation recommandé : 3–5 s, avec une temporisation exponentielle pouvant atteindre 30 s. Le délai d’expiration côté client dépend du SLA de votre application (la génération vidéo peut prendre plusieurs minutes).

Enregistrement du webhook

GEThttps://getvibeapi.com/api/webhooks
PATCHhttps://getvibeapi.com/api/webhooks

Une URL par compte : mediaWebhookUrl. Configurée dans dashboard → Webhooks ou via l’API avec une account session (un cookie après la connexion). L’endpoint n’accepte pas sk-pv-… : uniquement une session authentifiée.

# Example (a dashboard session is required, not an API key)
curl -X PATCH https://getvibeapi.com/api/webhooks \
  -H "Content-Type: application/json" \
  -b "session=YOUR_SESSION" \
  -d '{"mediaWebhookUrl":"https://example.com/webhooks/media"}'

# Clear the URL
curl -X PATCH https://getvibeapi.com/api/webhooks \
  -H "Content-Type: application/json" \
  -b "session=YOUR_SESSION" \
  -d '{"mediaWebhookUrl":null}'
Exigences relatives aux URL
ParamètreTypeDescription
mediaWebhookUrlURL HTTPSUne adresse HTTPS publique ; les adresses privées ou de bouclage et nos propres domaines sont refusés (protection contre les SSRF), et l’adresse est vérifiée à nouveau avant chaque livraison. Une chaîne vide ou null réinitialise ce paramètre.
balanceWebhookUrlURL HTTPSUn webhook distinct pour les soldes faibles (pas pour les médias), signé avec le même secret de compte, x-pv-event: balance.low. Le seuil est balanceWebhookThresholdRub.

Livraison du webhook à la fin du traitement

Lorsqu’une tâche atteint un statut final, GetVibe crée un événement logique unique et le distribue via POST au mediaWebhookUrl enregistré. La livraison est limitée : le service effectue au total jusqu’à 5 tentatives. Le même payload peut être reçu plusieurs fois.

// POST to your mediaWebhookUrl when a job finishes
{
  "jobId": "...",
  "status": "success",            // or "fail"
  "model": "veo-3.1",
  "kind": "video",                // image | video | audio | music | 3d
  "resultUrls": ["https://getvibeapi.com/api/media/file/..."],
  "failMsg": null,
  "createdAt": "2026-06-17T10:00:00.000Z"
}
Comportement de livraison (comme dans le code)
ParamètreTypeDescription
Signature / auth—Chaque livraison est signée selon la norme Standard Webhooks : les en-têtes webhook-id, webhook-timestamp et webhook-signature (v1, HMAC-SHA256 en base64 de « id.timestamp.body »). Le secret de compte est affiché dans le tableau de bord → Webhooks et renvoyé à une clé API sous le nom accountSecret par GET /api/media/webhook-secret ; les livraisons vers un webhook_url fourni par requête sont signées avec le secret de cette clé (le champ secret). Rejetez toute requête dont la signature est incorrecte ou dont l’horodatage date de plus de 5 minutes.
RetriesoutboxJusqu’à 5 tentatives au total ; intervalle après un échec : 1, 2, 4, 8 minutes. Après épuisement des tentatives, l’événement passe à FAILED et n’est plus livré automatiquement. La requête GET /api/media/jobs/{id} reste la source de l’état.
Receiver deduprequiredDédupliquez selon la paire jobId + status et rendez votre gestionnaire idempotent. N’utilisez pas le webhook comme unique source d’état.
Content-Typeapplication/jsonLe corps est un JSON contenant les champs jobId, status, model, kind, resultUrls, failMsg, createdAt.

Erreurs de POST /api/media/generate

HTTPQuandFraisRéessayer
202Tâche acceptée (ok: true, jobId)Non (uniquement après réussite)—
400JSON / corps de requête invalideNonCorriger la requête
401Clé API manquante ou non valideNonVérifier l’autorisation
402Solde insuffisant (admission)NonRecharger le solde
422Modèle inconnu, options non valides, ok: false renvoyé par la façadeNonFix model/opts
502media_submit_failed — service en amont indisponibleNonRéessayer avec temporisation progressive
503priceUnavailable, garde de routage, VIDEO_DISABLED, veo sans prixNonAutre modèle / ultérieurement

Erreurs d’interrogation et échecs terminaux

HTTP / statutSignificationFrais
404tâche introuvable ou jobId appartenant à un autre compteNon
processingLa tâche est toujours en cours d’exécutionNon
successTerminé, resultUrls renseignéOui — priceRub dans la réponse
failÉchec de la générationNo (priceRub = 0)

Facturation et idempotence

  • Facturé une seule fois en cas de succès. Dans finalizeJob, la transition processing → success|fail est atomique : un callback ou un sondage répété ne déclenche pas de seconde facturation.
  • fail — gratuit. Aucun débit n’est effectué pour un statut fail.
  • Cotation d’admission. Si une cotation a été enregistrée lors de la création, c’est exactement ce montant qui est facturé en cas de succès (jamais davantage que le décompte réel du fournisseur amont).
  • Créez l’idempotence — via un en-tête. Un POST répété vers /api/media/generate sans l’en-tête crée un nouveau job et une nouvelle facturation en cas de succès. Envoyez Idempotency-Key (jusqu’à 255 caractères ASCII) : une nouvelle tentative avec la même clé et le même corps dans les 24 heures renvoie le même jobId sans créer de nouveau job ; la même clé avec un corps différent renvoie 422, et 409 tant que la première requête est encore en cours de traitement. Le jobId d’une génération payante apparaît également dans GET /v1/generations (le champ job_id).
  • Le webhook est limité à cinq tentatives. Un événement logique est créé pour chaque transition finale, mais les tentatives de livraison peuvent se répéter. Après cinq échecs, l’événement reçoit le statut FAILED . Le gestionnaire client doit dédupliquer la paire jobId + status.
Voir aussi : Génération de médias, Catalogue des modèles de médias, Erreurs et limites (codes 401/402/429 courants pour /v1).
Webhooks média de GetVibe API — statuts, erreurs, facturation | GetVibe API