ClipMaster API
Automatisez ClipMaster en ligne de commande, depuis vos propres scripts ou avec un assistant IA. Les mêmes endpoints que l'app — décomptés avec les mêmes jetons, sans facturation séparée.
Vous préférez le texte brut ? Lire cette page en Markdown — pensé pour les LLM et les agents. Vous utilisez Claude ? Connectez le serveur MCP au lieu d'appeler les endpoints à la main.
Vue d'ensemble
Accédez à ClipMaster par le code avec une clé API. Chaque endpoint se comporte exactement comme dans l'app, limité à vos propres projets et clips. L'accès API est disponible avec les offres payantes.
URL de base :
https://api.clipmaster.app/api/v1
Authentification
Créez une clé dans l'app, sous Paramètres → Accès API. La clé complète (cm_live_…) n'est affichée qu'une fois, à la création — conservez-la en lieu sûr. Envoyez-la comme token Bearer dans l'en-tête Authorization :
curl https://api.clipmaster.app/api/v1/projects \-H "Authorization: Bearer cm_live_xxxxxxxxxxxxxxxxxxxx"
- En-tête uniquement. Les clés ne sont pas acceptées en paramètre de requête
?token=. - Une clé est rattachée à votre compte et agit en votre nom, limitée à vos propres données.
- Révoquez une clé à tout moment dans les Paramètres ; une clé révoquée cesse de fonctionner immédiatement.
403 session_auth_required pour la connexion/OAuth, la facturation et le paiement (la lecture de votre solde de jetons et de votre utilisation est autorisée), l'administration, la gestion des clés API et la connexion d'un canal social. Connectez d'abord votre canal dans l'application web — tout le reste est scriptable.Certains points de terminaison sont des fonctionnalités de forfaits payants, marqués ci-dessous avec le nom de la fonctionnalité (par exemple compilation). Sur un forfait sans cette fonctionnalité, ils répondent 403 subscription_required avec cette feature.
Limites de débit
120 requêtes par minute et par clé. Au-delà, vous recevez un 429 avec un en-tête Retry-After.
Les points de terminaison de l'IA (suggestions, Auto-édition, mesure audio, organisation) ont également leurs propres limites par utilisateur et répondent 429 de la même manière.
Démarrage rapide
Importez une vidéo YouTube, attendez la fin du traitement, puis listez et téléchargez les clips. Définissez ceci une fois dans votre shell :
KEY="cm_live_xxxxxxxxxxxxxxxxxxxx"BASE="https://api.clipmaster.app/api/v1"
Requête
curl -X POST "$BASE/upload/from-url" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"source_url": "https://youtube.com/watch?v=..."}
Réponse
{"project_id": 123,"task_id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890","message": "Processing started","progress_url": "/api/v1/projects/123/status"}
Requête
curl "$BASE/projects/123/status" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"status": "completed","progress": 1.0,"progress_percent": 100,"total_clips": 6,"processing_complete": true}
Requête
curl "$BASE/projects/123/clips" \-H "Authorization: Bearer $KEY"
Réponse
[{"clip_id": 456,"start_time": 0.0,"end_time": 42.3,"description": "Founder explains the pivot","status": "ready"}]
Requête
# Render it (charges tokens) -> {"export_id": 37, "status": "rendering", ...}curl -X POST "$BASE/projects/123/clips/456/export" \-H "Authorization: Bearer $KEY"# Poll until "status" is "completed"curl "$BASE/exports/37/status" -H "Authorization: Bearer $KEY"# The clip's exports, newest firstcurl "$BASE/exports?clip_id=456" -H "Authorization: Bearer $KEY"# Download from the newest completed export's download_urlcurl -L "$DOWNLOAD_URL" -o clip.mp4
Un téléchargement est toujours un export : le clip rendu avec ses sous-titres, effets et découpe enregistrés. download_url est un lien S3 signé, valable jusqu'au prochain 00:00 UTC (au moins 30 minutes) — sans en-tête d'authentification. Rappelez GET /exports pour obtenir un nouveau lien.
Import
Pour les fichiers, utilisez le flux de téléchargement en deux étapes ; pour YouTube, ingérez par URL. Les deux acceptent les mêmes champs optionnels : processing_mode (automatique, sémantique ou full_video), query, min_duration, orientation, les drapeaux de sous-titres, et compilation_format avec compilation_prompt pour construire une compilation une fois les clips prêts. Le traitement coûte 1 jeton par minute source.
Ingérer une URL YouTube. Le traitement commence immédiatement ; interrogez le statut du projet retourné. Payant : youtube_import.
Requête
curl -X POST "$BASE/upload/from-url" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"source_url": "https://youtube.com/watch?v=...","orientation": "vertical","compilation_format": "auto"}
Réponse
{"project_id": 123,"task_id": "a1b2c3d4-5e6f-7890-abcd-ef1234567890","message": "Processing started","metadata": { "duration_sec": 212.4, "resolution": "1920x1080" },"progress_url": "/api/v1/projects/123/status"}
Étape 1 de l'import d'un fichier. Renvoie une cible d'envoi de courte durée : envoyez le fichier en POST vers upload.url avec les upload.fields renvoyés tels quels, puis appelez complete.
Requête
curl -X POST "$BASE/uploads/init" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"filename": "talk.mp4","size_bytes": 94371840,"sha256": "e3b0c44298fc1c14...","duration_sec": 693.5,"content_type": "video/mp4"}
Réponse
{"project_id": 124,"upload": {"url": "https://uploads.clipmaster.app","fields": {"...": "opaque form fields - send them back unchanged"}},"expires_at": "2026-08-14T21:00:00Z"}
Étape 2 : confirmer la fin de l'envoi et lancer le traitement.
Requête
curl -X POST "$BASE/uploads/124/complete" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 124,"task_id": "b2c3d4e5-...","message": "Processing started","progress_url": "/api/v1/projects/124/status"}
Téléchargez un logo, une voix off ou un fichier de scène de compilation sans navigateur. purpose est logo, narration, scene_video ou scene_image (les deux derniers payants : compilation). POST les champs retournés, puis le fichier en dernier, vers upload.url dans les 15 minutes, puis utilisez la asset_key à /users/me/logo/from-upload, /projects/{id}/clips/{clip_id}/logo/from-upload, /compilations/{id}/narration/from-upload ou /compilations/{id}/media-scenes (comme upload_key).
Requête
curl -X POST "$BASE/uploads/assets" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"purpose": "logo", "content_type": "image/png", "size_bytes": 20480}'
Réponse
{"asset_key": "originals/staging/42/9f1c2b7e.png","upload": {"url": "https://s3.amazonaws.com/...","fields": { "...": "opaque form fields - send them back unchanged" }},"expires_at": "2026-09-11T21:15:00Z"}
Statut et clips
Interroger la progression du traitement. status vaut uploading, uploaded, processing, completed ou failed.
Requête
curl "$BASE/projects/123/status" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"status": "processing","progress": 0.45,"progress_percent": 45,"current_step": "Transcription","total_scenes": 8,"total_clips": 0,"processing_complete": false}
Lister les clips générés avec leurs métadonnées IA (accroche, type de clip, confiance).
Requête
curl "$BASE/projects/123/clips" \-H "Authorization: Bearer $KEY"
Réponse
[{"clip_id": 456,"start_time": 0.0,"end_time": 42.3,"description": "Founder explains the pivot","display_name": null,"status": "ready","source": "Clipmaster","streaming_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...","features": {"scene_id": 2265,"clip_duration": 42.3,"vision_analysis": {"hook": "The moment everything changed","clip_type": "story","confidence": 0.9}}}]
Détail complet pour un clip — un sur-ensemble de l'élément de liste : chaque champ de fonctionnalité, l'analyse IA de la scène, son rembourrage, son badge et sa viralité. Chaque image, l'audio et les mots sont dans GET …/analysis.
Requête
curl "$BASE/projects/123/clips/456" \-H "Authorization: Bearer $KEY"
Même structure que l'entrée de liste ci-dessus, avec l'objet features complet.
Lister vos projets.
Requête
curl "$BASE/projects" -H "Authorization: Bearer $KEY"
Réponse
[{"project_id": 123,"filename": "keynote.mp4","status": "completed","created_at": "2026-08-14T20:11:38Z","video_metadata": {"duration_sec": 693.5,"resolution": "1920x1080","detected_orientation": "horizontal"},"is_demo": false}]
Supprimer un projet avec tous ses clips, scènes et fichiers.
Requête
curl -X DELETE "$BASE/projects/123" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"success": true,"message": "Project deleted"}
Retranscrire toute la vidéo, en arrière-plan. Les clips avec leurs propres mots édités les conservent. Interrogez le statut pour project_config.transcription_rerun_status. Pas de jetons ; soumis à des limites de débit.
Requête
curl -X POST "$BASE/projects/123/transcription" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"status": "running","progress_url": "/api/v1/projects/123/status"}
Analyse
Lisez l'analyse, au format JSON, pour placer un montage sur ce qu'elle a trouvé. Les documents d'un clip utilisent le temps du spectateur — l'horloge des superpositions, des suggestions et de l'édition automatique : secondes à partir du début de sa scène. Le clip est lu de 0 à time.duration ; les temps en dehors de cela sont le rembourrage autour de la scène, où les superpositions ne peuvent pas aller. La liste des moments ne conserve que ce qui est lu, de sorte que chacun de ses t peut être placé tel quel ; à partir de l'analyse complète du clip, ne placez que les temps entre 0 et time.duration. Secondes vidéo = t + time.scene_start. Le document de la vidéo utilise les secondes à partir du début du téléchargement. Les boîtes sont des fractions {x, y, w, h} du cadre. La lecture est gratuite et fonctionne sur le projet de démonstration.
L'analyse complète stockée d'un clip. Sections : scene (description, accroche, sujet, type, score, badge, viralité), layout (coupes de caméra et, par image, le type de plan, les visages et les panneaux écran/webcam), audio (fort, silencieux, rythme, chant ; onsets=true ajoute chaque coup), transcript (les mots du clip, avec les locuteurs si connus), sound_events (rires, applaudissements, musique), video_moments, talk_scenes et auto_edit (la prise stockée, avec ses plages de vitesse). include sélectionne les sections, séparées par des virgules ; toutes par défaut.
Requête
curl "$BASE/projects/123/clips/456/analysis?include=scene,layout,audio" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"clip_id": 456,"scene_id": 2265,"time": {"clock": "viewer","unit": "seconds","note": "0 = scene start, …","duration": 10.0,"scene_start": 100.0,"scene_end": 110.0,"clip_start": -2.0,"clip_end": 12.0},"analyses": {"layout": {"status": "completed","error": null,"step": null,"started_at": "2026-10-22T18:02:11+00:00","finished_at": "2026-10-22T18:02:40+00:00","what": "Faces, screen/webcam/gameplay panels, shot type per frame, camera cuts.","rest": "POST /api/v1/projects/123/clips/456/layout-analysis","mcp": "analyze_clip_layout","cost": "Paid plans (smart crop); no tokens."},"audio_cues": { "status": "completed", "...": "same fields" },"auto_edit": { "status": null, "...": "same fields" }},"scene": {"description": "He grabs the rim and the crowd erupts","hook": "The dunk nobody saw coming","topic": "basketball","clip_type": "reaction","score": 8,"...": "the rest of its stored AI fields","badge": { "label": "Highlight", "key": "highlight", "color": "#FF6B6B" },"virality": { "tier": "hot", "label": "Hot", "color": "#FF4444" }},"layout": {"current": true,"faces_placeable": true,"analyzed_at": "2026-10-22T18:02:40+00:00","model": "gemini-3.5-flash-lite","frame_interval": 2.0,"frame_size": { "width": 1920, "height": 1080 },"cuts": [4.0],"frames": [{ "t": 0.0, "shot": "solo_talking_head","faces": [{ "x": 0.4, "y": 0.1, "w": 0.2, "h": 0.4 }], "panels": [] },{ "t": 4.0, "shot": "screen_share_with_webcam","faces": [{ "x": 0.8, "y": 0.04, "w": 0.12, "h": 0.18 }],"panels": [{ "kind": "webcam_overlay", "x": 0.75, "y": 0.0, "w": 0.25, "h": 0.25,"highlighted": true }] }]},"audio": {"current": true,"measured_at": "2026-10-22T18:01:05+00:00","has_audio": true,"median_active_db": -20.0,"loud": [{ "t": 4.0, "end": 4.5, "over_db": 9.0 }],"quiet": [{ "start": -2.0, "end": -0.5, "level_db": -48.0 }],"beat": [{ "start": 0.0, "end": 10.0, "tempo_bpm": 120.0, "first_beat": 0.1, "period": 0.5 }],"singing": null}}
time et analyses sont toujours présents. analyses contient une entrée par exécution à la demande (layout, audio_cues, auto_edit) : status est running, completed, failed, stale (marqué running depuis plus de 30 minutes, donc il est probablement mort — vérifiez à nouveau avant de le redémarrer) ou null (jamais exécuté), avec error, step (la dernière étape atteinte ; significatif pendant l'exécution), les horodatages et le point de terminaison qui le démarre. layout, audio et auto_edit sont null tant qu'ils n'ont pas été exécutés ; sound_events, video_moments et talk_scenes sont [] lorsque rien n'a été trouvé. current: false signifie que le résultat ne correspond plus au clip : son fichier vidéo a été coupé à nouveau depuis (un simple rognage ne le change pas), pour layout également lorsque la dernière exécution n'a pas été terminée, pour audio également lorsque la mesure elle-même a changé. Un rognage rend auto_edit current: false, car ses temps sont sur l'horloge de la scène ; une prise plus ancienne qui n'a pas enregistré sa scène lit current: null (inconnu). Les temps audio sont convertis à partir du fichier sur lequel ils ont été mesurés. Une section inconnue est 400 unknown_section.
Le clip sous forme d'une liste unique triée par temps {t, kind, source, …} : cut, shot et faces (lorsque le nombre de plans ou de visages change), les prises de parole speaker, sound, loud, quiet, beat, singing et les moments du passage de vision. Seul ce qui est lu est listé — les étendues coupées à 0–time.duration, un plan, un nombre de visages ou un orateur défini dans le rembourrage ramené à 0, tout le reste dans le rembourrage laissé de côté — de sorte que chaque t va à POST …/overlays tel quel. Une analyse de mise en page ou audio qui ne correspond plus au clip est omise et nommée dans stale. Avec le summary de la scène, quelles analyses sont available, et analyses. Même horloge que l'analyse du clip.
Requête
curl "$BASE/projects/123/clips/456/moments" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"clip_id": 456,"time": { "clock": "viewer", "duration": 10.0, "...": "as in …/analysis" },"summary": {"description": "He grabs the rim and the crowd erupts","hook": "The dunk nobody saw coming","topic": "basketball","clip_type": "reaction","score": 8},"available": { "layout": true, "audio": true, "transcript": true, "video_moments": true },"stale": [],"analyses": { "...": "as in …/analysis" },"moments": [{ "t": 0.0, "kind": "beat", "source": "audio", "end": 10.0, "tempo_bpm": 120.0 },{ "t": 0.0, "kind": "faces", "source": "layout", "count": 1 },{ "t": 0.0, "kind": "shot", "source": "layout", "detail": "solo_talking_head" },{ "t": 0.0, "kind": "speaker", "source": "transcript", "speaker": "speaker_0", "first_word": "Here" },{ "t": 1.0, "kind": "moment", "source": "video", "end": 3.0, "detail": "action_peak","score": 8, "description": "Rim grab" },{ "t": 3.0, "kind": "sound", "source": "transcript", "end": 4.0, "detail": "laughter" },{ "t": 4.0, "kind": "cut", "source": "layout" },{ "t": 4.0, "kind": "loud", "source": "audio", "end": 4.5, "over_db": 9.0 },{ "t": 4.0, "kind": "shot", "source": "layout", "detail": "screen_share_with_webcam" }]}
La vidéo entière, sur le temps vidéo : metadata, la transcript par segment avec les orateurs, sound_events, les video_moments du passage de vision et les talk_scenes du passage de transcription (chacun avec un …_status et un bloc …_pass : le statut et le modèle du passage, plus l'erreur et le temps du passage de vision), et chaque scène avec son accroche, son score et son indicateur degraded (vrai : l'étape de scène de l'IA a échoué et c'est un repli de longueur fixe non scoré). include sélectionne les sections ; words (chaque mot, avec l'orateur et la confiance) n'apparaît que lorsqu'il est nommé. analyses.transcription signale une re-transcription.
Requête
curl "$BASE/projects/123/analysis" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"time": { "clock": "video", "unit": "seconds", "note": "Seconds from the start of the upload." },"analyses": {"transcription": {"status": null,"...": "same fields as a clip's runs","rest": "POST /api/v1/projects/123/transcription","mcp": "transcribe_video"}},"metadata": { "duration_sec": 693.5, "resolution": "1920x1080", "detected_orientation": "horizontal","...": "the rest of the upload's metadata" },"transcript": {"language": "english","provider": "openai_whisper","duration": 693.5,"no_audio": false,"speakers": [],"segments": [{ "start": 99.0, "end": 106.0, "text": "Here we go.", "speaker": null }]},"sound_events": [{ "t": 103.0, "end": 104.0, "kind": "laughter", "label": "[laughter]","speaker": null, "confidence": null }],"video_moments": [{ "start": 101.0, "end": 103.0, "type": "action_peak", "score": 8,"description": "Rim grab" }],"video_moments_status": "ok","video_moments_pass": { "status": "ok", "error": null, "model": "gemini-3.8-flash","analyzed_at": "2026-10-22T17:40:12+00:00" },"talk_scenes": [{ "start": 95.0, "end": 105.0, "clip_type": "story", "score": 7,"hook": "Why he almost quit", "topic": "basketball","description": "He tells how the season started", "confidence": 0.8 }],"talk_scenes_status": "ok","talk_scenes_pass": { "status": "ok", "model": "gpt-4o-mini" },"scenes": [{ "scene_id": 2265, "start": 100.0, "end": 110.0, "source": "merged","description": "He grabs the rim and the crowd erupts","hook": "The dunk nobody saw coming", "topic": "basketball","clip_type": "reaction", "score": 8, "degraded": false }]}
Mesurez l'audio du clip — moments forts, passages calmes, rythme et tempo, chant — en arrière-plan. Interrogez GET …/analysis jusqu'à ce que analyses.audio_cues.status soit terminé ou échoué ; le résultat est sa section audio. Suggérer et l'édition automatique le mesurent eux-mêmes ; appelez ceci pour lire l'audio en premier. 409 audio_cues_running, audio_cues_current (la mesure stockée correspond toujours au fichier du clip) ou clip_file_missing. Payant : ai_suggestions ; pas de jetons ; partage une limite de débit avec les effets Suggérer et l'édition automatique.
Requête
curl -X POST "$BASE/projects/123/clips/456/audio-cues" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"clip_id": 456,"status": "running"}
Édition
Tout ce que l'éditeur intégré à l'application fait est scriptable : découpage, sous-titres et leur traduction, mises en page, zooms, effets d'écran, vitesse, emojis, GIFs, stickers, clips de réaction, effets sonores, logo, barre de progression et orientation.
Deux horloges. Les superpositions que vous ajoutez (POST …/overlays) et chaque suggestion utilisent le temps du spectateur — secondes depuis le début du clip tel qu'il est lu. Les paramètres enregistrés conservent les temps par rapport au fichier de clip rembourré, quelques secondes de plus à chaque extrémité ; le point de terminaison des superpositions convertit pour vous.
Découpe — déplacer le début/la fin d'un clip. Tous les clips de la scène se mettent à jour automatiquement.
Requête
curl -X PUT "$BASE/projects/123/scenes/2265/boundaries" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"new_start_time": 12.0,"new_end_time": 27.5}
Réponse
{"scene_id": 2265,"project_id": 123,"old_start_time": 0.0,"old_end_time": 42.3,"new_start_time": 12.0,"new_end_time": 27.5,"message": "Scene boundaries updated successfully."}
Lire ou mettre à jour l'état complet de l'éditeur : sous-titres (avec secondary pour une deuxième ligne), emojis, GIFs, stickers et clips de réaction (gifs, distingués par kind), sfx, zoom, screenEffects, cadrage, logo, barre de progression, orientation, speed et speedRanges. PUT remplace l'objet entier — renvoyez tout ce que GET a retourné, avec vos modifications ; tout ce qui est omis est effacé.
Requête
curl -X PUT "$BASE/projects/123/clips/456/settings" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"orientation": "vertical","captions": {"enabled": true,"style": "hormozi","karaoke": true},"speed": 1.25}
Réponse
{"clip_id": 456,"settings": {"captions": { "enabled": true, "style": "hormozi", "karaoke": true },"zoom": null,"screenEffects": null,"logo": null,"progressBar": null,"smartCrop": null,"gifs": null,"orientation": "vertical","speed": 1.25,"speedRanges": null}}
Un zoom est une forme : {type: "zoom", start, end, scale, glide, target, center} — entre à start (avec glide secondes pour y arriver, 0 pour un déclenchement instantané), maintenu à scale (1.05–2.5), revient à end, ou maintenu jusqu'à la fin du clip lorsque end est nul. Les anciens zooms punch et lents sont convertis.
Lire ou remplacer les mots des sous-titres, avec un minutage au mot près.
Requête
curl -X PUT "$BASE/projects/123/clips/456/captions" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"words": [{ "text": "Use", "start": 28.06, "end": 28.14 },{ "text": "correct", "start": 28.14, "end": 28.22 }]}
Réponse
{"words": [{ "text": "Use", "start": 28.06, "end": 28.14, "highlight": null },{ "text": "correct", "start": 28.14, "end": 28.22, "highlight": null }]}
Renommer un clip. Une chaîne vide rétablit le nom généré.
Requête
curl -X PATCH "$BASE/projects/123/clips/456/name" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"name": "Best hook"}
Réponse
{"clip_id": 456,"display_name": "Best hook"}
Retranscrire l'audio de ce clip et faire du résultat ses sous-titres. Remplace les mots édités ; répond avec les nouveaux mots. Pas de jetons ; soumis à des limites de débit.
Requête
curl -X POST "$BASE/projects/123/clips/456/transcribe" \-H "Authorization: Bearer $KEY"
Ajoutez des superpositions au moment où le spectateur les voit : emojis, inline_emojis, gifs, stickers, reaction_clips, sfx, zooms, screen_effects et speed_ranges. La conversion de temps de l'éditeur et les valeurs par défaut sont appliquées pour vous, et les suggestions IA peuvent être envoyées telles qu'elles sont arrivées. Cela ne fait qu'ajouter.
Requête
curl -X POST "$BASE/projects/123/clips/456/overlays" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"emojis": [{ "emoji": "🔥", "timestamp": 12.0 }],"inline_emojis": [{ "emoji": "💰", "word_index": 5 }],"gifs": [{ "source_id": "k1", "slug": "mind-blown", "mp4_url": "https://…","width": 480, "height": 270, "timestamp": 8.0 }],"sfx": [{ "sfx_id": 3, "timestamp": 3.0, "volume": 0.4 }],"zooms": [{ "start": 20.0, "length": 1.0, "scale": 1.3 }],"screen_effects": [{ "look": "flash", "start": 20.0 }],"speed_ranges": [{ "start": 31.0, "length": 2.5, "speed": 2.0 }]}
Réponse
{"clip_id": 456,"settings": {"emojis": [{ "type": "floating", "emoji": "🔥", "timestamp": 14.0, "duration": 1.0,"position": { "x": 0.5, "y": 0.694 }, "scale": 1.0 }],"zoom": [{ "type": "zoom", "start": 22.0, "end": 23.0, "scale": 1.3, "glide": 0,"target": "frame", "center": { "x": 0.5, "y": 0.5 } }]}}
Un clip contient jusqu'à 5 GIFs, 5 stickers et 5 clips de réaction. Le spot sur un emoji ou un sticker suit le visage principal, et target: "face" sur un zoom zoome dessus — payant (smart_crop), après l'analyse de la mise en page du clip.
Une deuxième ligne de sous-titres dans une autre langue. GET liste les langues que ce clip possède déjà et celles prises en charge ; POST {"language": "es"} le traduit — 1 jeton, gratuit si le clip l'a déjà. Payant : caption_translation. Il s'affiche une fois que captions.secondary est défini dans les paramètres.
Requête
curl -X POST "$BASE/projects/123/clips/456/translations" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"language": "es"}'
Réponse
{"project_id": 123,"language": "es","lines": [{ "text": "Usa la palabra correcta", "start": 28.06, "end": 29.4 }],"created": true,"tokens_charged": 1}
Analysez ce que chaque moment du clip montre — types de plans, visages, panneaux écran et webcam — en arrière-plan. Nécessaire avant que les incrustations puissent suivre un visage. Interrogez le clip pour features.vision_analysis.layout_rerun_status, ou GET …/analysis pour analyses.layout.status ; chaque image est sa section layout. Payant : smart_crop ; pas de jetons.
Requête
curl -X POST "$BASE/projects/123/clips/456/layout-analysis" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"clip_id": 456,"status": "running"}
Téléchargez (multipart, champ file) ou supprimez un logo par clip. Sans navigateur, préparez-le avec POST /uploads/assets et attachez-le à …/logo/from-upload.
Requête
curl -X POST "$BASE/projects/123/clips/456/logo/from-upload" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"asset_key": "originals/staging/42/9f1c2b7e.png"}'
Suggestions IA et Auto-édition
Les suggestions sont en lecture seule : elles renvoient des placements sur le temps du spectateur, prêts à être envoyés à POST …/overlays tels qu'ils sont arrivés. Payant : ai_suggestions. Pas de jetons ; soumis à des limites de débit.
Suggestions pour un clip. kind est gifs, stickers, reaction-clips, emojis, sfx, effects (recettes de zoom et d'effets d'écran) ou speed (temps morts accélérés, ralenti). Paramètre de requête max_suggestions.
Requête
curl -X POST "$BASE/projects/123/clips/456/gifs/suggest?max_suggestions=3" \-H "Authorization: Bearer $KEY"
Réponse
{"clip_id": 456,"suggestions": [{"source_id": "k1","slug": "mind-blown","title": "Mind Blown","mp4_url": "https://…","width": 480,"height": 270,"preview_url": "https://…","timestamp": 8.0,"duration": 2.0,"query": "mind blown","reason": "Reacts to the reveal"}]}
effects et speed répondent avec audio_cues_ready: false tant que l'audio du clip est encore en cours de mesure — redemandez quelques secondes plus tard. Une suggestion de vitesse est {start, end, speed} : envoyez-la avec length = end − start.
Planifiez un montage complet pour le clip — zooms, effets d'écran, stickers, sons et plages de vitesse — en arrière-plan. Interrogez le clip pour features.vision_analysis.auto_edit_rerun_status ; le montage est features.vision_analysis.auto_edit ({effects, stickers, sfx, speed}, également la section auto_edit de GET …/analysis). Rien n'est appliqué : envoyez ses parties à POST …/overlays. Payant : ai_suggestions ; pas de jetons.
Requête
curl -X POST "$BASE/projects/123/clips/456/auto-edit" \-H "Authorization: Bearer $KEY"
Réponse
{"project_id": 123,"clip_id": 456,"status": "running"}
Export
Lancer le rendu d'un clip avec ses réglages enregistrés. Renvoie un identifiant d'export à interroger ; consomme des jetons.
Requête
curl -X POST "$BASE/projects/123/clips/456/export" \-H "Authorization: Bearer $KEY"
Réponse
{"export_id": 37,"status": "rendering","message": "Export render triggered"}
Interroger un export. Une fois terminé, download_url est un lien temporaire qui expire — récupérez le fichier sans tarder.
Requête
curl "$BASE/exports/37/status" \-H "Authorization: Bearer $KEY"
Réponse
{"export_id": 37,"status": "completed","download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...","created_at": "2026-08-14T21:47:35Z","completed_at": "2026-08-14T21:48:42Z"}
Liste vos exports, du plus récent au plus ancien. Filtrez avec clip_id ou project_id. C'est ainsi qu'on télécharge un clip : prenez l'export le plus récent au statut completed et récupérez son download_url.
Requête
curl "$BASE/exports?clip_id=456" \-H "Authorization: Bearer $KEY"
Réponse
{"exports": [{"export_id": 37,"clip_id": 456,"project_id": 123,"status": "completed","progress": null,"export_number": 2,"tokens_charged": 1,"clip_duration_sec": 42.3,"download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...","created_at": "2026-08-14T21:47:35Z","completed_at": "2026-08-14T21:48:42Z"}],"total": 2,"limit": 20,"offset": 0}
Compilations
Une compilation est un montage construit à partir de clips de n'importe laquelle de vos vidéos. La création, l'arrangement et l'exportation d'une compilation sont payants : compilation.
Lister vos compilations (collections de clips multi-projets).
Requête
curl "$BASE/compilations" -H "Authorization: Bearer $KEY"
Réponse
{"items": [{"id": 10,"name": "Funny Personal Anecdotes","clip_count": 5,"total_duration_sec": 149.9,"output": { "width": 1920, "height": 1080, "fps": 30 },"format": null,"latest_export": null,"created_at": "2026-08-10T19:05:41Z"}]}
Créez une compilation vide. Payant : compilation.
Requête
curl -X POST "$BASE/compilations" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"name": "Best of March","output": { "width": 1080, "height": 1920, "fps": 30 }}
Lisez une compilation — ses clips, estimated_tokens pour une exportation, le plan de montage dans arrangement_metadata.edit_plan et les fichiers qu'elle lit dans media — ou modifiez son name, output, logo_config ou progress_bar_config.
Requête
curl "$BASE/compilations/10" -H "Authorization: Bearer $KEY"
Ce que la suppression entraînerait : les téléchargements qui n'existent que pour cette compilation, et les publications en attente.
Requête
curl "$BASE/compilations/10/deletion-preview" -H "Authorization: Bearer $KEY"
Réponse
{"compilation_id": 10,"source_project_ids": [],"scheduled_posts_pending": 0}
Supprimez une compilation ; ses publications en attente sont annulées. delete_sources=true supprime également les téléchargements de l'aperçu ; passez-les comme expected_project_ids et la suppression est refusée (409) si cet ensemble a changé.
Requête
curl -X DELETE "$BASE/compilations/10" \-H "Authorization: Bearer $KEY"
Réponse
{"compilation_id": 10,"deleted_project_ids": [],"scheduled_posts_cancelled": 0}
Vos clips de toutes les vidéos, à ajouter. Paramètres de requête q, limit, offset.
Requête
curl "$BASE/compilations/available-clips?q=pivot&limit=50" \-H "Authorization: Bearer $KEY"
Ajoute un clip (clip_id, position facultatif). DELETE /compilations/{id}/clips/{compilation_clip_id} en supprime un.
Requête
curl -X POST "$BASE/compilations/10/clips" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"clip_id": 456}'
Plus de clips de votre bibliothèque qui correspondent à cette compilation, les meilleurs en premier.
Requête
curl -X POST "$BASE/compilations/10/clips/suggest" \-H "Authorization: Bearer $KEY"
Idées de compilations de votre bibliothèque pour un brief. Transformez-en une en compilation avec POST /compilations/from-suggestion (name, clip_ids).
Requête
curl -X POST "$BASE/compilations/suggest" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"prompt": "funny moments", "max_suggestions": 3}'
Réponse
{"suggestions": [{"theme": "Funny moments","reason": "Five clips where the audience laughs","clip_ids": [456, 457, 461],"total_duration_sec": 94.2}]}
Rend la compilation. Débite des jetons pour les secondes de la source qu'elle lit (estimated_tokens sur la compilation).
Requête
curl -X POST "$BASE/compilations/10/export" \-H "Authorization: Bearer $KEY"
Réponse
{"export_id": 5,"compilation_id": 10,"status": "pending","estimated_tokens": 3,"message": "Export started"}
Interroge l'exportation d'une compilation ; download_url fonctionne comme pour l'exportation d'un clip. GET /compilations/{id}/exports les liste.
Requête
curl "$BASE/compilations/10/exports/5/status" \-H "Authorization: Bearer $KEY"
Réponse
{"export_id": 5,"compilation_id": 10,"status": "completed","progress": null,"download_url": "https://clipmaster-media.s3.amazonaws.com/...mp4?...&Expires=...","created_at": "2026-08-14T21:47:35Z","completed_at": "2026-08-14T21:50:02Z"}
Édition de compilation
Une compilation est un plan de montage : des scènes d'un à trois panneaux (un clip ou un fichier) avec des transitions et des cartes de texte, plus des superpositions, de la musique et une voix off sur l'ensemble du montage. Les temps sont en secondes dans la compilation.
Recoupe la compilation avec l'IA en un nouveau plan de scènes. format : personnalisé (un montage ; nécessite prompt), best_of, countdown, trailer, hook_loop, tutorial, qa_highlights ou auto. Remplace les scènes et les emojis et GIFs qui y sont épinglés ; les légendes, la musique et la narration restent.
Requête
curl -X POST "$BASE/compilations/10/arrange" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"format": "hook_loop"}
Réponse
{"id": 10,"name": "Funny Personal Anecdotes","format": "hook_loop","total_duration_sec": 58.2,"estimated_tokens": 1,"clips": [{ "compilation_clip_id": 88, "position": 0, "clip_id": 456, "duration_sec": 12.4, "missing": false }],"arrangement_metadata": {"resolved_format": "hook_loop","degraded": false,"edit_plan": {"version": "2.0","scenes": [{"id": "1","layout": "full","sources": [{ "clip_id": 456, "slot": 0, "audio": "primary","start_offset_sec": 3.0, "end_offset_sec": 9.5, "speed": 1.0 }],"text": []}]}}}
degraded: true signifie que l'étape IA a échoué et que les clips ont été conservés dans l'ordre.
plan/undo revient à l'état avant la dernière organisation, réinitialisation ou placement (refait à nouveau) ; plan/reset fait une coupe simple, chaque clip entier ; plan/place-added-clips intègre les clips ajoutés depuis l'édition IA. Pas de corps.
Requête
curl -X POST "$BASE/compilations/10/plan/undo" \-H "Authorization: Bearer $KEY"
Recoupe une scène avec l'IA, en laissant le reste. prompt facultatif. Les identifiants de scène sont du texte.
Requête
curl -X POST "$BASE/compilations/10/scenes/3/regenerate" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"prompt": "use the boat clip instead"}'
Donne un motif rythmique à une scène : de courtes répétitions muettes de son clip sur les temps de la musique, juste avant elle. pattern : stutter, quick_stutter, build_up, jump_cut, teaser, ou null pour le retirer. Nécessite une musique mesurée (409 music_not_measured d'ici là).
Requête
curl -X PUT "$BASE/compilations/10/scenes/3/beat-pattern" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"pattern": "stutter"}'
Remplace le plan d'édition. Mises en page : full (1 panneau), stack2 / cols2 / pip (2), stack3 / cols3 (3). Une source lit un clip_id ou une media_key ; ses décalages sont le début et la fin de la fenêtre en secondes dans la scène du clip ; au plus une source par scène est l'audio primary. Transitions : cut, fade, slide, wipe. Les superpositions omises sont conservées ; la music omise est supprimée.
Requête
curl -X PUT "$BASE/compilations/10/plan" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"version": "2.0","scenes": [{"id": "1","layout": "full","sources": [{ "clip_id": 456, "audio": "primary","start_offset_sec": 2.0, "end_offset_sec": 14.5 }],"text": [{ "text": "Day one", "role": "title", "start_ms": 0, "duration_ms": 2000 }]},{"id": "2","layout": "stack2","transition_in": { "kind": "fade", "duration_ms": 400 },"sources": [{ "clip_id": 457, "slot": 0, "audio": "primary", "speed": 1.5 },{ "clip_id": 458, "slot": 1 }]}],"music": { "track_id": "a1b2c3", "volume": 0.3 }}
POST ajoute des emojis, des GIFs, des stickers, des zooms, des effets d'écran et des effets sonores sur l'ensemble du montage, dans les formes des superpositions de clips. PATCH remplace un ensemble stocké entier à la place (captions, emojis, gifs, screenEffects, zoom, sfx) ; seul ce que vous envoyez change.
Requête
curl -X POST "$BASE/compilations/10/plan/overlays" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"emojis": [{ "emoji": "🎉", "timestamp": 3.0 }],"screen_effects": [{ "look": "bw", "start": 10.0, "length": 2.0 }]}
Réponse
{"id": 10,"arrangement_metadata": {"edit_plan": {"emojis": [{ "type": "floating", "emoji": "🎉", "timestamp": 3.0, "duration": 1.0,"position": { "x": 0.5, "y": 0.694 }, "scale": 1.0 }]}}}
Modifiez toute la compilation en une seule fois et appliquez-la, en ne remplissant que ce qui est vide : comment chaque scène arrive (toute transition disponible), cartes de texte (mots, police, taille, position, timing), une piste de bibliothèque, des plages de vitesse sur les clips à vitesse normale et la barre de progression, plus des zooms, des effets d'écran, des stickers, des GIFs, des emojis, des effets sonores et jusqu'à 2 scènes de clips de réaction. direction (facultatif, jusqu'à 300 caractères) dirige le tout et est conservé pour la prochaine exécution. Envoyez le take retourné à …/auto-edit/undo pour le retirer, ou de nouveau ici en tant que replace_take pour l'échanger contre un nouveau. Payant : compilation ; pas de jetons.
Requête
curl -X POST "$BASE/compilations/10/auto-edit" \-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \-d '{"direction": "hype energy, big bold text"}'
Réponse
{"compilation": { "id": 10, "...": "as GET /compilations/{id}" },"take": {"scene_ids": ["r1"],"effect_ids": ["e1", "e2"],"sticker_ids": ["g1"],"emoji_ids": ["m1"],"zoom_ids": ["z1"],"sfx_ids": ["s1"],"transitions": [{ "scene_id": "2", "kind": "slide", "duration_ms": 400 }],"text_cards": [{ "scene_id": "1", "text": "Best of the year" }],"music_track_id": "lib-42","speed_ranges": [{ "scene_id": "2", "slot": 0, "start": 24.0, "end": 25.2, "speed": 0.5 }],"progress_bar": true},"counts": { "effects": 2, "stickers": 0, "gifs": 1, "emojis": 1,"reaction_clips": 1, "zooms": 1, "sounds": 1, "transitions": 1,"texts": 1, "music": 1, "speed_ranges": 1, "progress_bar": 1 }}
L'audio mesuré du montage, sur sa propre horloge : le rythme de la musique (ou d'un clip audible), les moments forts, les passages calmes et le chant ; onsets=true ajoute chaque attaque. Chaque audio est mesuré une fois, en arrière-plan, la première fois qu'il est lu ou qu'il rejoint le montage — sources indique ceux qui sont mesurés et measuring reste à true jusqu'à ce qu'ils le soient tous. Les lumières de fête y prennent beat_first, beat_period et beat_clock. Payant : compilation ; pas de jetons.
Requête
curl "$BASE/compilations/10/audio" \-H "Authorization: Bearer $KEY"
Réponse
{"compilation_id": 10,"duration_sec": 37.4,"measuring": false,"sources": [{ "kind": "music", "status": "measured", "track_id": "lib-42" },{ "kind": "clip", "status": "measured", "scene_id": "1", "clip_id": 1621 }],"beat": [{ "start": 12.0, "end": 37.4, "first_beat": 12.02, "period": 0.38,"tempo_bpm": 157.9, "clock": "edit" }],"loud": [{ "t": 33.0, "end": 33.4, "over_db": 11.0 }],"quiet": [{ "start": 3.4, "end": 9.0, "level_db": -38.0 }],"singing": [],"onsets": null}
Ajoute une scène qui lit un fichier au lieu d'un clip : un clip de réaction Klipy (klipy) ou une vidéo ou image téléchargée (upload_key). Elle vient après after_scene_id, ou en dernier ; into_scene_id en fait un panneau supplémentaire à côté des clips de cette scène. La vidéo téléchargée compte pour les jetons de l'exportation ; les clips de réaction et les images sont gratuits. Payant : compilation.
Requête
curl -X POST "$BASE/compilations/10/media-scenes" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"klipy": { "source_id": "c3", "slug": "emotional-damage","title": "Emotional Damage", "mp4_url": "https://…" },"after_scene_id": "2"}
Une voix off sur l'ensemble du montage, transcrite pour les légendes. POST la télécharge (multipart, champ file) ou attache une voix off préparée à …/narration/from-upload ; PATCH définit le volume et le duck ; DELETE la supprime.
Requête
curl -X POST "$BASE/compilations/10/narration/from-upload" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"asset_key": "originals/staging/42/5d8e1a.mp3"}'
Réponse
{"url": "https://clipmaster-media.s3.amazonaws.com/...mp3?...","volume": 1.0,"duck": true,"duration_sec": 61.4,"word_count": 152}
Pistes qui correspondent au montage, chacune avec une raison. Prenez-en une avec POST /music/tracks/{track_id}/select, puis définissez music.track_id dans le plan.
Requête
curl -X POST "$BASE/compilations/10/music/suggest" \-H "Authorization: Bearer $KEY"
Suggestions pour l'ensemble du montage, sur ses propres secondes : kind est gifs, stickers ou emojis. Envoyez-les à POST …/plan/overlays. Payant : compilation.
Requête
curl -X POST "$BASE/compilations/10/emojis/suggest" \-H "Authorization: Bearer $KEY"
Réponse
{"compilation_id": 10,"suggestions": [{ "emoji": "😂", "timestamp": 14.2, "duration": 1.5, "reason": "The punchline lands" }]}
Lignes de titre et d'étiquette pour une scène.
Requête
curl -X POST "$BASE/compilations/10/scenes/1/text/suggest" \-H "Authorization: Bearer $KEY"
Réponse
{"suggestions": [{ "text": "Day one", "role": "title" }]}
Programmation
Publiez des clips et des compilations sur une chaîne connectée. La programmation nécessite une offre qui inclut la programmation sociale.
Vos chaînes connectées. Connectez-les d'abord dans l'app web.
Requête
curl "$BASE/social/accounts" -H "Authorization: Bearer $KEY"
Réponse
{"platforms_available": ["youtube"],"accounts": [{"id": 2,"platform": "youtube","account_name": "MyChannel","status": "active"}]}
Programmer la publication d'un export de clip ou de compilation. Idempotent — une nouvelle tentative avec le même compte, le même export et la même heure renvoie la publication existante.
Requête
curl -X POST "$BASE/scheduled-posts" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d @body.json
Corps de la requête
{"social_account_id": 2,"clip_id": 456,"export_id": 37,"scheduled_at": "2026-08-20T16:00:00Z","title": "The pivot that saved us","hashtags": ["startup", "founder"],"privacy": "public"}
Réponse
{"id": 12,"clip_id": 456,"export_id": 37,"social_account_id": 2,"platform": "youtube","account_name": "MyChannel","status": "scheduled","scheduled_at": "2026-08-20T16:00:00","title": "The pivot that saved us"}
Plage de calendrier des publications programmées et publiées.
Requête
curl "$BASE/scheduled-posts?from_date=2026-08-01T00:00:00Z&to_date=2026-08-31T23:59:59Z" \-H "Authorization: Bearer $KEY"
Réponse
{"posts": [{"id": 12,"status": "scheduled","scheduled_at": "2026-08-20T16:00:00","title": "The pivot that saved us"}]}
Redate ou modifie une publication avant qu'elle ne soit publiée (scheduled_at, title, description, hashtags, privacy), ou l'annule.
Requête
curl -X PATCH "$BASE/scheduled-posts/12" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"scheduled_at": "2026-08-21T16:00:00Z"}'
Titre, description et hashtags IA à partir de la transcription d'un clip.
Requête
curl -X POST "$BASE/scheduled-posts/metadata-suggest" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \-d '{"clip_id": 456, "platform": "youtube"}'
Réponse
{"title": "The pivot that saved us","description": "How one decision turned the company around.","hashtags": ["startup", "founder"]}
Déconnecte une chaîne. Son historique de publications, en attente et publiées, disparaît avec elle.
Requête
curl -X DELETE "$BASE/social/accounts/2" \-H "Authorization: Bearer $KEY"
Bibliothèque
Lister les 15 styles de sous-titres et leurs valeurs par défaut.
Requête
curl "$BASE/export/styles" \-H "Authorization: Bearer $KEY"
Réponse
[{"key": "clean","name": "Clean","category": "social","fontFamily": "Inter","fontSize": 56,"color": "#FFFFFF","highlightColor": "#9DC34F"}]
La bibliothèque d'effets sonores ; ses identifiants vont dans les superpositions sfx. category facultatif.
Requête
curl "$BASE/sfx" -H "Authorization: Bearer $KEY"
Recherche Klipy, ou liste ce qui est tendance. kind est gif, sticker ou clip (clips de réaction). Placez un résultat avec id comme source_id et mp4.url comme mp4_url ; un sticker nécessite également image.url comme image_url.
Requête
curl "$BASE/gifs/search?q=mind%20blown&kind=sticker&per_page=10" \-H "Authorization: Bearer $KEY"
Réponse
{"items": [{"id": "s9","slug": "mind-blown-sticker","title": "Mind Blown","kind": "sticker","mp4": { "url": "https://….webm", "width": 320, "height": 320 },"preview": { "url": "https://….webp", "width": 160, "height": 160 },"image": { "url": "https://….webp", "width": 320, "height": 320 }}],"page": 1,"per_page": 10,"has_next": true}
Recherche de musique de fond. genre, duration_min, duration_max facultatifs.
Requête
curl "$BASE/music/search?q=upbeat" -H "Authorization: Bearer $KEY"
Prenez une piste dans votre bibliothèque afin qu'une compilation puisse l'utiliser.
Requête
curl -X POST "$BASE/music/tracks/a1b2c3/select" \-H "Authorization: Bearer $KEY"
Compte
Votre solde de jetons : total, réservé par les tâches en cours et disponible.
Requête
curl "$BASE/billing/balance" -H "Authorization: Bearer $KEY"
Réponse
{"balance": 120,"reserved": 3,"available": 117,"total_purchased": 200,"total_spent": 80}
Ce que vous avez utilisé au cours des period derniers jours (1-365).
Requête
curl "$BASE/billing/usage?period=30" -H "Authorization: Bearer $KEY"
Réponse
{"period_days": 30,"tokens_spent": 42,"tokens_purchased": 0,"uploads_count": 6,"exports_count": 11,"minutes_processed": 38.5,"minutes_exported": 7.9}
Erreurs
Les erreurs comportent un code lisible par une machine :
{"detail": {"error": "insufficient_tokens","message": "Not enough tokens for this operation"}}
Codes courants : api_access_required / session_auth_required (403), subscription_required (403, nomme la feature du plan), insufficient_tokens (402), export_in_progress / export_expired (409). Une clé incorrecte ou révoquée renvoie 401 ; un dépassement de limite de débit renvoie 429.
Coût en jetons
Mesuré exactement comme l'application — 1 jeton = 1 minute source pour le traitement d'un téléchargement ou d'une importation YouTube ; les exportations sont facturées selon les règles de l'application (une compilation par les secondes sources qu'elle joue) ; une traduction de sous-titre de clip coûte 1 jeton. Les suggestions, l'Auto-édition, l'organisation, l'analyse de la mise en page, la mesure audio et la re-transcription ne dépensent pas de jetons. Il n'y a pas de facturation API séparée.