Documentation API

Référence complète de l'API REST Viffly.app

Authentification

L'API supporte deux méthodes d'authentification. Les deux nécessitent un plan Business ou supérieur pour les appels externes.

Méthode 1 : Clé API (recommandée)
curl -X POST https://viffly.app/api/generate-sync \
  -H "X-API-Key: vf_votre_cle_api" \
  -F "audio=@narration.mp3" \
  -F "title=Ma vidéo"
Méthode 2 : Bearer Token
# Obtenir un token via /api/login
# session : "short" (12 h) | "default" (7 j) | "long" (30 j)
curl -X POST https://viffly.app/api/login \
  -H "Content-Type: application/json" \
  -d '{"email":"vous@email.com","password":"...","session":"short"}'

# Réponse : { "token": "eyJhbG...", "expires_at": "...", "session_ttl": "12h" }

# Utiliser le token
curl -H "Authorization: Bearer eyJhbG..." \
  https://viffly.app/api/me
Les Bearer Tokens expirent après 12 h, 7 j ou 30 j selon le paramètre `session`. Les clés API (vf_...) sont scopées, révocables, renouvelables et limitées en débit individuellement : c'est la méthode à utiliser en production.
Portée des clés (scopes)

Chaque clé porte une liste de scopes. Un appel vers un endpoint non couvert est refusé avec un 403 nommant le scope manquant — accordez le minimum nécessaire.

ScopeEndpoints couverts
generate/api/ltx/* · /api/generate · /api/generate-sync · talking-head · restyle · montage · longshort · loop-assemble · director · slideshow · reframe · autocut · audio-clean · watermark · voiceover · media-jobs
ai_images/api/image-jobs · /api/generate-images · /api/images/edit · /api/characters/*
ai_script/api/ai/*
videos/api/videos
credits/api/me · /api/credits/*

Une clé sans scope enregistré (créée avant l'introduction des scopes) passe partout. Renouvelez-la pour lui appliquer une portée.

Cycle de vie des clés
  • 5 clés maximum par compte. Le secret complet n'est affiché qu'à la création — il n'est jamais réaffichable.
  • Limite de débit réglable par clé (60 req/min par défaut, 1000 au maximum). Un dépassement renvoie 429 avec un en-tête Retry-After.
  • Expiration au choix : 7, 30, 90, 365 jours ou jamais. Une clé expirée est refusée sans être supprimée.
  • Rotation : un nouveau secret remplace l'ancien instantanément, en conservant nom, scopes et limites. À utiliser dès qu'une clé a pu fuiter.
# Renouveler le secret d'une clé (nom, scopes et limites conservés)
curl -X POST https://viffly.app/api/keys/{id}/rotate \
  -H "Authorization: Bearer eyJhbG..."

# Déconnecter tous les autres appareils
curl -X POST https://viffly.app/api/account/revoke-sessions \
  -H "Authorization: Bearer eyJhbG..."

Système de crédits

Chaque opération IA consomme des crédits (coût fixe pour les fonctions classiques, à la durée pour la vidéo IA). Les opérations gratuites (Pexels, Whisper) ne consomment rien.

🎬
Rendu vidéo
5 cr.
📝
Script IA
1 cr.
🎙️
Voix IA
4 cr.
🖼️
Image IA (×1)
2 cr.
🎵
Musique IA
5 cr.
💡
Prompt images
Gratuit
📷
Images Pexels
Gratuit
💬
Transcription
Gratuit
Exemples : Vidéo budget (votre audio + Pexels) = 5 cr. | Vidéo standard (script + voix IA) = 10 cr. | Vidéo full IA (tout automatique) = 21 cr.
GET/api/credits/costs

Retourne le coût en crédits de chaque opération, les plans disponibles et des scénarios d'utilisation.

Réponse
{
  "costs": { "render": 5, "ai_script": 1, "ai_voice": 4, "ai_image": 2, "ai_music": 5, "pexels": 0 },
  "packages": [
    { "slug": "free", "label": "Free", "monthlyCredits": 15 },
    { "slug": "pro", "label": "Pro", "monthlyCredits": 200 }, ...
  ],
  "scenarios": [ { "name": "Budget", "credits": 5 }, ... ]
}
GET/api/meAuth

Retourne les informations du compte, incluant le solde de crédits.

Réponse
{
  "id": "abc123",
  "client_email": "vous@email.com",
  "package": "pro",
  "creditsTotal": 142,
  "creditsMonthly": 130,
  "creditsPack": 12,
  "monthlyAllowance": 150,
  "packageLabel": "Pro",
  "creditCosts": { "render": 5, "ai_voice": 4, ... }
}

Génération vidéo IA (MiniMax / Alibaba)

Génère une vidéo à partir d'un texte (t2v) ou d'une image (i2v) via les modèles IA. C'est l'API à utiliser depuis n8n. Le flux est asynchrone : on soumet un job, puis on interroge son statut jusqu'à done.

🌊 Hailuo 2.3 (MiniMax)
MiniMax Hailuo 2.3 · model: "hailuo23"
🎬 Wan 2.2
Alibaba Wan 2.7 · model: "wan27"
Nécessite un plan Pro ou supérieur. Authentification par X-API-Key.
GET/api/ltx/pricing

Liste les tiers (résolution × durée), les ratios d'aspect et les scénarios. Aucune auth requise — utile pour peupler une UI ou choisir un tier_id.

Réponse
{
  "tiers": [
    { "id": "tier1", "label": "720p · 5s",  "resolution": "720p",  "seconds": 5,  "credits": 10 },
    { "id": "tier2", "label": "720p · 5s",  "resolution": "720p",  "seconds": 5,  "credits": 10 },
    { "id": "tier3", "label": "720p · 10s", "resolution": "720p",  "seconds": 10, "credits": 20 },
    { "id": "tier6", "label": "1080p · 5s", "resolution": "1080p", "seconds": 5,  "credits": 10 },
    { "id": "tier7", "label": "1080p · 10s","resolution": "1080p", "seconds": 10, "credits": 20 }
  ],
  "models": [
    { "id": "wan27", "provider": "dashscope_wan", "tiers": [...] },
    { "id": "hailuo23", "provider": "minimax_hailuo", "tiers": [...] }
  ],
  "aspects": [ { "id": "9:16" }, { "id": "1:1" }, { "id": "16:9" } ],
  "scenarios": [ { "id": "cinematic" }, { "id": "product" }, ... ],
  "default_negative": "ugly, blurry, low quality, ..."
}
POST/api/ltx/generate10 cr.Auth

Soumet un job de génération vidéo. Retourne immédiatement un job_id (ne bloque pas). Body en JSON.

Corps de la requête
ChampTypeDescription
mode*string"t2v" (texte→vidéo) ou "i2v" (image→vidéo)
prompt*stringDescription de la vidéo (≥ 3 caractères)
tier_idstringtier1, tier2, tier3, tier6 ou tier7. Consultez /pricing pour les combinaisons du moteur.
modelstring"hailuo23" (MiniMax), "happyhorse" ou "wan27" (Alibaba)
image_base64stringImage de départ en base64 (requis si mode=i2v). Sans préfixe data:
image_urlstringAlternative: URL publique HTTPS de l'image de départ (i2v)
negativestringPrompt négatif (défaut: voir /api/ltx/pricing)
aspectstring"9:16" (défaut), "1:1", "16:9"
scenario_typestringDirection créative (voir /api/ltx/pricing)
fpsnumberImages/seconde (défaut: 24)
seednumberGraine (reproductibilité). Aléatoire si omis
audio_onbooleanGarder la piste audio générée (défaut: true)
Réponse
{
  "job_id": "915c93ea-58b7-4808-a83f-5dfa98ee1ef5",
  "status": "processing",
  "tier": { "id": "tier2", "label": "720p · 5s", "credits": 10 }
}
Exemple — texte → vidéo :
curl -X POST https://viffly.app/api/ltx/generate \
  -H "X-API-Key: vf_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "t2v",
    "model": "hailuo23",
    "prompt": "a sports car drifting on a coastal road at sunset, cinematic",
    "tier_id": "tier2",
    "aspect": "9:16"
  }'
Exemple — image → vidéo :
curl -X POST https://viffly.app/api/ltx/generate \
  -H "X-API-Key: vf_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "i2v",
    "model": "wan27",
    "prompt": "slow cinematic push in, gentle motion",
    "tier_id": "tier2",
    "image_base64": "'"$(base64 -w0 photo.jpg)"'"
  }'
POST/api/ltx/generate-sync10 cr.Auth

Version SYNCHRONE : soumet, attend le rendu en interne, puis renvoie la vidéo — en UN seul appel (pas de boucle wait/poll). Idéal pour un node n8n unique. Mets un timeout long (ex. 1200000 ms).

Corps de la requête
ChampTypeDescription
(identique à /api/ltx/generate)*jsonmode, prompt, tier_id, model, image_base64/image_url, aspect…
Réponse
// Par défaut → renvoie le FICHIER MP4 (binaire). Dans n8n : Response Format = File.
// Avec ?format=json → renvoie l'URL à la place :
{
  "status": "done",
  "job_id": "915c93ea-...",
  "output_url": "/videos/ltx_915c93ea-....mp4",
  "url": "https://viffly.app/videos/ltx_915c93ea-....mp4"
}
# Récupère directement le MP4 (sortie binaire)
curl -X POST https://viffly.app/api/ltx/generate-sync \
  -H "X-API-Key: vf_votre_cle" -H "Content-Type: application/json" \
  -d '{"mode":"t2v","model":"hailuo23","prompt":"...","tier_id":"tier2"}' \
  --max-time 1200 -o video.mp4

# Ou récupère juste l'URL (JSON)
curl -X POST "https://viffly.app/api/ltx/generate-sync?format=json" \
  -H "X-API-Key: vf_votre_cle" -H "Content-Type: application/json" \
  -d '{"mode":"t2v","prompt":"...","tier_id":"tier2"}'
GET/api/ltx/status/:idAuth

(Mode async) Interroge l'état d'un job. À appeler en boucle (toutes les ~5-10 s) jusqu'à status = done ou error. Inutile si tu utilises /generate-sync.

Réponse
// en cours
{ "id": "915c93ea-...", "status": "processing", "progress": 50 }

// terminé
{
  "id": "915c93ea-...",
  "status": "done",
  "output_url": "/videos/ltx_915c93ea-....mp4",  // relatif → préfixer https://viffly.app
  "progress": 100
}

// échec (crédits remboursés)
{ "id": "915c93ea-...", "status": "error", "error": "..." }
output_url est relatif. URL de téléchargement complète = https://viffly.app + output_url.

Miniatures intelligentes

Transforme une vidéo horizontale, verticale ou carrée en miniatures multi-formats. Choisis des frames réelles, des frames retouchées par IA ou de nouveaux visuels générés depuis le sujet et la transcription.

16:9 · 9:16 · 1:1 · 4:5Recadrage intelligent par destination
1–6 × formatMoments réellement différents
Async · n8n readyJobs durables avec suivi de progression
POST/api/thumbnails5 cr.Auth

Lance un job depuis une URL vidéo, une source S3 autorisée ou un fichier déjà hébergé par Viffly.

Corps de la requête
ChampTypeDescription
source_url*stringURL HTTPS publique, s3:// autorisé ou /videos/...
countnumber1 à 6 variantes par format (défaut : 3)
formatsstring[]auto, 16:9, 9:16, 1:1, 4:5
visual_modestringframes (défaut), enhance ou generate
ai_qualitystringstandard (2 cr./image) ou premium (5 cr./image)
image_promptstringDirection facultative pour la retouche ou la génération
languagestringLangue du titre automatique : auto, fr, en, ar, es, de ou pt
titlestringTitre optionnel ; généré depuis le contenu si omis
subtitlestringSous-titre optionnel
stylestringeditorial, bold, clean, minimal
tonestringauto, warm, cool, mono
smartbooleanAnalyse visuelle + transcription + point focal
include_textbooleanAjouter ou non la composition typographique
accentstringCouleur hexadécimale, ex. #6D4AFF
Réponse
{
  "job_id": "53a9c34d-...",
  "status": "processing",
  "cost": 11,
  "visual_mode": "generate",
  "cost_breakdown": { "composition": 5, "ai_images": 6 },
  "outputs_planned": 3,
  "status_url": "/api/thumbnails/53a9c34d-..."
}
curl -X POST https://viffly.app/api/thumbnails \
  -H "X-API-Key: vf_votre_cle" \
  -H "Content-Type: application/json" \
  -d '{
    "source_url": "https://cdn.exemple.com/video.mp4",
    "count": 3,
    "formats": ["16:9", "9:16"],
    "visual_mode": "generate",
    "ai_quality": "standard",
    "language": "fr",
    "image_prompt": "documentary editorial visual, authentic texture, no text",
    "style": "editorial",
    "smart": true
  }'
POST/api/thumbnails/upload5 cr.Auth

Upload multipart pratique pour n8n et les fichiers jusqu’à 200 Mo.

Corps de la requête
ChampTypeDescription
video*fileMP4, MOV, M4V, MKV, WebM, AVI ou MPEG · 200 Mo max
formatsstringTableau JSON ou liste séparée par des virgules
countnumber1 à 6 variantes par format
visual_modestringframes, enhance ou generate
ai_qualitystringstandard ou premium
image_promptstringDirection facultative pour l’IA
languagestringLangue du titre automatique : auto, fr, en, ar, es, de ou pt
stylestringeditorial, bold, clean, minimal
Réponse
{ "job_id": "53a9c34d-...", "status": "processing", "status_url": "/api/thumbnails/53a9c34d-..." }
curl -X POST https://viffly.app/api/thumbnails/upload \
  -H "X-API-Key: vf_votre_cle" \
  -F "video=@episode.mp4" \
  -F 'formats=["16:9","9:16"]' \
  -F "count=3" \
  -F "visual_mode=enhance" \
  -F "ai_quality=standard" \
  -F "language=fr" \
  -F "image_prompt=cinematic light, cleaner background" \
  -F "style=editorial"
GET/api/thumbnails/:idAuth

Suit le job et retourne l’analyse, les frames source et toutes les miniatures finales.

Réponse
{
  "job_id": "53a9c34d-...",
  "status": "done",
  "progress": 100,
  "analysis": { "summary": "..." },
  "visual_mode": "enhance",
  "outputs": [
    { "url": "/videos/thumb_....jpg", "format": "16:9", "source_kind": "enhanced", "master_url": "/videos/mmedit_....png", "raw_frame_url": "/videos/thumb_..._frame_1.jpg", "width": 1280, "height": 720, "timestamp": 42.1, "score": 91 }
  ]
}
n8n

Chaîne recommandée : HTTP Request POST → Wait 3 s → HTTP Request GET → IF status = done. Boucle sur Wait tant que le statut est processing.

GET https://viffly.app/api/thumbnails/{{ $('Viffly · Miniatures').item.json.job_id }}

Webhooks — être notifié à la fin d'un rendu

Ajoutez callback_url à n'importe quelle création de travail : au lieu d'interroger le statut en boucle, Viffly vous envoie un POST dès que le rendu est terminé. Votre exécution n8n ou Make ne reste jamais bloquée pendant plusieurs minutes.

POST /api/ltx/generate
{
  "mode": "i2v",
  "prompt": "…",
  "callback_url": "https://votre-domaine.com/viffly-hook"
}

L'adresse doit être en HTTPS et publiquement joignable. Les adresses privées, localhost et le HTTP simple sont refusés à la création, avant tout débit de crédits.

Ce que vous recevez
{
  "event": "job.completed",      // ou "job.failed"
  "job_id": "3f2a…",
  "kind": "video",
  "status": "done",              // ou "error"
  "output_url": "/videos/ltx_3f2a….mp4",
  "error": null,
  "delivered_at": "2026-07-27T19:44:12.031Z"
}
En-têtes
X-Viffly-Eventnom de l'événement, identique au champ event du corps
X-Viffly-Deliveryidentifiant unique de la livraison — servez-vous-en pour ignorer un doublon
X-Viffly-Timestamphorodatage unix en secondes, entrant dans le calcul de la signature
X-Viffly-Signaturesha256=… — HMAC du corps, permet de vérifier que l'appel vient bien de nous
Vérifier la signature

Calculez le HMAC-SHA256 de « horodatage.corps » avec votre secret et comparez-le à l'en-tête. Utilisez le corps BRUT de la requête : re-sérialiser le JSON change les espaces et invalide la comparaison.

const crypto = require('crypto');

function verifie(req, secret) {
  const ts   = req.headers['x-viffly-timestamp'];
  const recu = req.headers['x-viffly-signature'];
  const attendu = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(ts + '.' + req.rawBody)   // corps BRUT, non re-sérialisé
    .digest('hex');
  return crypto.timingSafeEqual(Buffer.from(recu), Buffer.from(attendu));
}

En cas d'échec, jusqu'à 4 tentatives espacées (immédiate, +2 s, +15 s, +60 s). Une réponse 4xx est considérée comme un refus définitif et n'est pas retentée. Renvoyez un 2xx dès réception.

Intégration n8n — node HTTP Request

Le flux vidéo est asynchrone. Dans n8n, le pattern est : SoumettreAttendreVérifier le statut → boucler tant que ≠ done.

① HTTP Request (POST /generate)② Wait 10s③ HTTP Request (GET /status)④ IF status = done ?→ non : retour ②→ oui : télécharger
Constructeur de node n8n

Configure les options ci-dessous puis génère le JSON du node HTTP Request — copie-le et colle-le directement dans le canvas n8n (Ctrl+V), ou télécharge le fichier.

Ou configure les nodes à la main :
NODE 1Soumettre le job — HTTP Request
MethodPOST
URLhttps://viffly.app/api/ltx/generate
AuthenticationNone (on passe la clé en header ci-dessous)
Send HeadersON → Name: X-API-Key | Value: vf_votre_cle
Send BodyON → Body Content Type: JSON
Specify BodyUsing JSON
Body (JSON)
{
  "mode": "i2v",
  "model": "hailuo23",
  "prompt": "{{ $json.prompt }}",
  "tier_id": "tier2",
  "aspect": "9:16",
  "image_base64": "{{ $binary.data.data }}"
}

i2v : si l'image vient d'un node précédent (ex. Telegram, Read Binary File), référence sa donnée binaire base64 avec {{ $binary.data.data }}. Pour t2v, retire image_base64 et mets "mode": "t2v".

NODE 2 + 3Attendre puis vérifier le statut

Node 2 — Wait : 10 secondes. Node 3 — HTTP Request (poll) :

MethodGET
URLhttps://viffly.app/api/ltx/status/{{ $('NODE 1').item.json.job_id }}
Send HeadersON → X-API-Key: vf_votre_cle
NODE 4Boucler — IF status = done ?

Node IF — condition (String) : {{ $json.status }} equals done.

  • false (pas encore prêt) → relie la sortie vers le Node 2 (Wait) : la boucle continue.
  • true (terminé) → continue. L'URL finale = https://viffly.app{{ $json.output_url }}
Télécharger la vidéo (HTTP Request)
MethodGET
URLhttps://viffly.app{{ $json.output_url }}
Response FormatFile / Binary
Astuces n8n
  • Pour éviter une boucle infinie : ajoute un compteur (Set node + IF sur un max d'itérations, ex. 60 ≈ 10 min).
  • Wan 2.2 prend 3-5 min : mets le Wait à 15-20 s pour réduire le nombre d'appels.
  • Le coût est débité une fois au lancement et remboursé automatiquement si le rendu échoue.
  • Pas de webhook entrant : c'est du polling. Une clé API vf_… (onglet « API ») suffit.

Génération reel (audio + images)

POST/api/generate-sync5 cr.Auth

Génère une vidéo et attend le résultat (timeout 20 min). Retourne l'URL de téléchargement.

Corps de la requête
ChampTypeDescription
audio*fileFichier audio MP3 de la narration
imagesfile[]Images (1 à 4 fichiers). Alternative : image_url
image_urlstringURL d'une image (alternative à images)
image_url_0..NstringURLs d'images indexées, sans limite de 3 (jusqu'à 30 médias). Une URL .mp4/.mov placée ici joue comme clip vidéo à cette position.
mediastring[]Tableau JSON ordonné mêlant images ET vidéos — l'ordre du tableau = l'ordre d'affichage. Vidéos détectées par extension (.mp4, .mov, .webm…).
formatstringFormat de sortie : 9:16 (défaut), 16:9, 1:1, 4:5, 4:3
titlestringTitre affiché dans l'intro
sourcestringSource / nom du site
script_textstringTexte du script pour les sous-titres
templatestring32 templates : default, bold, clean, news, minimal, highlight, cinematic, neon, retro, gaming, story, meme, comic, glitch, noir, vaporwave, duotone, matrix, ticker…
caption_stylestringkaraoke, glow, outline, neon, block, shadow, gradient, typewriter
caption_sizestringS, M, L, XL
caption_positionstringtop, center, bottom
languagestringfr, en, ar, es, de, it, pt
profilestringNom du profil de rendu (ex: shadesplays)
music_urlstringURL de musique de fond (boucle automatiquement si la vidéo est plus longue que la piste)
music_start_atnumberOffset de démarrage musique (secondes)
voice_typestring"ai" pour narration MiniMax (+4 cr.)
voice_idstringID de voix MiniMax
outro_textstringTexte de l'écran de fin
outro_substringSous-titre de l'écran de fin
Réponse
{
  "videoId": "7865aac1-c301-4060-bd6e-6ca4fe3f6859",
  "url": "https://s3.eu-west-3.amazonaws.com/.../render.mp4",
  "thumbnail": "https://s3.eu-west-3.amazonaws.com/.../thumb.jpg",
  "duration": 27.5,
  "size": 8542190
}
Exemple complet :
curl -X POST https://viffly.app/api/generate-sync \
  -H "X-API-Key: vf_votre_cle" \
  -F "audio=@narration.mp3" \
  -F "format=16:9" \
  -F 'media=["https://cdn.exemple.com/clip.mp4","https://cdn.exemple.com/photo1.jpg","https://cdn.exemple.com/photo2.jpg"]' \
  -F "title=Mon titre" \
  -F "source=MonSite.com" \
  -F "template=gaming" \
  -F "caption_style=karaoke" \
  -F "caption_size=L" \
  -F "script_text=Voici le texte des sous-titres" \
  -F "profile=shadesplays"
POST/api/generate5 cr.Auth

Démarre la génération en arrière-plan. Retourne un jobId pour suivre la progression via SSE.

Réponse
{ "jobId": "e9e2d4f9-..." }
Suivre la progression : GET /api/videos/events?jobId=... (Server-Sent Events)

Vidéos

GET/api/videosAuth

Liste toutes les vidéos du compte, triées par date décroissante.

Réponse
[
  {
    "id": "7865aac1-...",
    "title": "Mon titre",
    "status": "done",
    "url": "https://...",
    "thumbnail": "https://...",
    "size": 8542190,
    "duration": 27.5,
    "created": "2026-03-28T..."
  }, ...
]
GET/api/videos/:id.mp4Auth

Télécharger le fichier MP4 d'une vidéo.

DELETE/api/videos/:idAuth

Supprimer une vidéo et ses fichiers associés.

Services IA

POST/api/ai/script1 cr.Auth

Génère un script de narration optimisé pour la viralité.

Corps de la requête
ChampTypeDescription
prompt*stringSujet ou instruction
existingstringScript existant à améliorer
contextstringContexte supplémentaire (contenu web)
languagestringLangue cible (fr, en, ar...)
Réponse
{ "script": "Saviez-vous que...", "charsUsed": 342, "charsMax": 700 }
POST/api/generate-images2 cr.Auth

Génère des images via FAL Flux 2 Pro.

Corps de la requête
ChampTypeDescription
prompt*stringDescription de l'image
countnumberNombre d'images (1-3, défaut: 3)
Réponse
{ "images": ["https://fal.media/...", ...] }
Coût : 2 crédits × nombre d'images
POST/api/ai/image-promptAuth

Génère 3 prompts d'images optimisés pour un sujet donné.

Corps de la requête
ChampTypeDescription
topic*stringSujet de la vidéo
stylestringStyle visuel souhaité
Réponse
{ "prompts": ["A cinematic...", "An aerial...", "A close-up..."] }
POST/api/generate-music5 cr.Auth

Génère une musique de fond via MiniMax Music.

Corps de la requête
ChampTypeDescription
promptstringDescription du style musical
stylestringGenre musical (pop, electronic, cinematic...)
instrumentalbooleanInstrumental uniquement (défaut: true)
titlestringTitre du morceau
Réponse
{ "taskId": "abc123", "status": "pending" }
Vérifier le statut : GET /api/generate-music/:taskId
GET/api/voicesAuth

Liste les voix MiniMax disponibles (cache 1h).

Réponse
{ "voices": [{ "voice_id": "pNInz6ob...", "name": "Adam", "labels": {...} }, ...] }

Gestion des clés API

GET/api/keysAuth

Liste toutes vos clés API.

Réponse
[{
  "id": "uuid", "name": "Production", "key_prefix": "vf_a1b2c3d4",
  "scopes": ["generate","videos"], "rate_limit": 60,
  "expires_at": null, "last_used_at": "2026-03-28T...",
  "usage_count": 42, "is_active": true
}]
POST/api/keysAuth

Crée une nouvelle clé API. La clé complète n'est retournée qu'à la création.

Corps de la requête
ChampTypeDescription
namestringNom de la clé (ex: Production)
scopesstring[]Permissions: generate, videos, credits, ai_script, ai_images, ai_music
rate_limitnumberRequêtes par minute (1-1000, défaut: 60)
expires_in_daysnumberJours avant expiration (null = jamais)
Réponse
{
  "id": "uuid",
  "key": "vf_a1b2c3d4e5f6...",  // ⚠️ Affiché UNE SEULE FOIS
  "name": "Production",
  "scopes": ["generate", "videos", "credits"]
}
PATCH/api/keys/:idAuth

Modifier une clé (nom, permissions, rate limit, activer/désactiver).

Corps de la requête
ChampTypeDescription
namestringNouveau nom
is_activebooleanActiver/désactiver
scopesstring[]Nouvelles permissions
rate_limitnumberNouveau rate limit
DELETE/api/keys/:idAuth

Supprime définitivement une clé API.

Bibliothèque médias

GET/api/musicAuth

Liste la bibliothèque musicale (pistes uploadées + MiniMax).

GET/api/pexels/imagesAuth

Recherche d'images Pexels.

Corps de la requête
ChampTypeDescription
qqueryTerme de recherche
pagequeryPage (défaut: 1)
per_pagequeryRésultats par page (défaut: 20)
GET/api/pexels/videosAuth

Recherche de vidéos Pexels.

Codes d'erreur

CodeSignificationAction
401Token invalide ou expiréRenouveler le token ou créer une nouvelle clé API
402Crédits insuffisantsAcheter un pack ou passer au plan supérieur
403Plan insuffisant (Business+ requis)Upgrader vers Business ou Agency
429Rate limit dépasséAttendre 1 minute ou augmenter le rate limit
500Erreur serveurRéessayer ou contacter le support
Format d'erreur standard
{
  "error": "Message descriptif de l'erreur",
  "creditsNeeded": 5  // (optionnel) crédits nécessaires
}
Rate limiting

Les limites par défaut sont :

  • Clés API : configurable par clé (1-1000 req/min, défaut 60)
  • Bearer Token : 100 req/min global
  • Endpoints IA (script, images, musique) : 10 req/min
  • Génération vidéo : 3 concurrentes max par compte