Expédiez votre premier travail multimédia en quelques minutes.
Fournissez à MediaRuntime une URL de média accessible, demandez exactement les sorties nécessaires et recevez un webhook terminal signé. Utilisez l'endpoint de téléversement facultatif uniquement si vous ne disposez pas déjà d'une URL source.
Créez la tâche, attendez, puis téléchargez le bundle ZIP.
Le CLI accepte les chemins de fichiers locaux relatifs ou absolus et téléverse automatiquement les octets. MediaRuntime accepte aussi directement une URL HTTP(S) publique ou une URL de lecture signée à durée limitée. Pour le premier essai, utilisez l’option --download du CLI ou le helper job.wait() d’un SDK afin de recevoir le bundle ZIP canonique. En production, conservez job_id et traitez le webhook signé du compte plutôt que d'interroger l'API.
# Submit a public or time-limited HTTPS source directly.
# Keep the URL fetchable until MediaRuntime has downloaded the input.
curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "https://cdn.example.com/media/launch-trailer.mp4",
"metadata": { "asset_id": "asset_0426", "media_type": "video" },
"outputs": ["video.web"]
}'Clonez un démarrage rapide complet
Des projets exécutables avec les SDK Node.js et Python, des exemples HTTP Go et PHP, des récepteurs de webhooks signés et un guide Postman sont réunis dans un dépôt public.
# Optional: use this when you have local bytes but no fetchable source URL.
UPLOAD=$(curl -sS -X POST "https://mediaruntime.com/v1/upload-url" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename":"launch-trailer.mp4","content_type":"video/mp4"}')
UPLOAD_URL=$(printf '%s' "$UPLOAD" | jq -r .upload_url)
FILE_URI=$(printf '%s' "$UPLOAD" | jq -r .file_uri)
UPLOAD_CONTENT_TYPE=$(printf '%s' "$UPLOAD" | jq -r '.upload_headers["Content-Type"]')
UPLOAD_AUTH=$(printf '%s' "$UPLOAD" | jq -r '.upload_headers.Authorization // empty')
UPLOAD_ARGS=(-H "Content-Type: $UPLOAD_CONTENT_TYPE")
if [[ -n "$UPLOAD_AUTH" ]]; then
UPLOAD_ARGS+=(-H "Authorization: $UPLOAD_AUTH")
fi
curl -sS -X PUT "$UPLOAD_URL" "${UPLOAD_ARGS[@]}" \
--upload-file ./launch-trailer.mp4
# Then use "$FILE_URI" as source in POST /v1/jobs.{
"job_id": "job_1320c28b72104811b075a26a99496cf6",
"status": "QUEUED",
"tier": "standard",
"required_tier": "standard",
"outputs": [{
"alias": "video.web",
"type": "mp4",
"preset": "mp4_720p_h264_aac"
}],
"msg": "accepted"
}Exécutez et inspectez vos traitements média depuis le terminal.
Le CLI officiel est le moyen le plus rapide de traiter des fichiers locaux, diagnostiquer la production, télécharger les bundles et tester un récepteur webhook local. Le CLI et les SDK Node et Python sont des packages 1.x stables dont les interfaces documentées suivent le versionnage sémantique. Ils utilisent le même contrat public et conservent le bundle ZIP comme résultat canonique.
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3Envoyer un fichier local et télécharger le bundle complet
Passez un chemin relatif comme ./launch.mp4 ou un chemin local absolu ; le CLI le téléverse automatiquement avant de créer la tâche. Dans un terminal interactif, un indicateur affiche les phases de téléversement, d’attente et de téléchargement vérifié. --download attend le résultat terminal et publie le ZIP canonique de manière atomique. Les fichiers existants sont conservés sauf si --force est explicite.
# The CLI uploads this local file before creating the job.
# Relative paths such as ./launch.mp4 work too.
mediaruntime run "/Users/you/Videos/launch.mp4" \
-o video.streaming \
-o audio.transcription \
--metadata '{"asset_id":"launch-01"}' \
--idempotency-key 'asset:launch-01:v1' \
--download ./launch-01.zipDécouvrir le catalogue public en direct
mediaruntime capabilities résume les alias et les fonctionnalités, tandis que mediaruntime presets list renvoie le catalogue public ordonné des presets. Ces commandes en lecture seule ne nécessitent ni connexion par navigateur ni MEDIARUNTIME_API_KEY.
# Public discovery commands do not require login or an API key.
mediaruntime capabilities
mediaruntime presets list
# Use JSON when another tool will consume the catalog.
mediaruntime presets list --jsonExécuter des presets publics précis
Utilisez --preset de façon répétée pour des entrées précises du catalogue telles que DASH ou VP9. Le CLI valide chaque nom auprès du catalogue public en direct avant de créer la tâche ; les alias et les presets précis peuvent être combinés dans l’ordre demandé.
# Preset names are validated against the live public catalog.
mediaruntime run ./launch.mp4 \
--preset dash_ladder_v1 \
--preset webm_vp9_1080p \
--download ./adaptive-and-vp9.zipInspecter et récupérer les traitements
Listez une page de traitements du compte, filtrez par état, inspectez un traitement ou téléchargez son bundle ZIP conservé. Utilisez le curseur opaque affiché par jobs list pour demander la page suivante.
mediaruntime jobs list --status COMPLETED --limit 20
mediaruntime jobs get job_123
mediaruntime jobs get job_123 --download ./job_123.zipUtiliser des clés API pour l’automatisation
Les CI, serveurs et conteneurs doivent injecter MEDIARUNTIME_API_KEY depuis un gestionnaire de secrets. Ne placez jamais d’identifiants dans les arguments, le contrôle de source, les journaux ou des fichiers de configuration en clair.
# Permanently supported for CI, servers, and containers.
export MEDIARUNTIME_API_KEY="sk_..."
mediaruntime jobs list --limit 3| Capacité | Contrat de commande | Notes |
|---|---|---|
| Alias de sortie | --output video.web | Les six alias figés sont acceptés ; répétez --output pour plusieurs livrables. |
| Sortie machine | --json | Écrit un seul résultat JSON compact sans URL signée pour les scripts et la CI. |
| Relances sûres | --idempotency-key | Réutilisez une clé métier pour le même traitement logique après un redémarrage du processus. |
| Sécurité du bundle | --download / --force | Télécharge uniquement les bundles terminaux, vérifie l’intégrité annoncée et refuse un écrasement accidentel. |
| Code de sortie | 0–9, 130 | L’authentification, le rejet API, l’échec terminal, le délai, le trigger et le bundle ont des codes non nuls distincts. |
export MEDIARUNTIME_WEBHOOK_SECRET="whsec_..."
mediaruntime trigger job.completed \
--to http://127.0.0.1:3000/webhooks/mediaruntimeConservez les clés API sur votre serveur.
Créez une clé à partir de Compte → Paramètres développeur → Clés API. La clé brute est affichée une fois et appartient à votre gestionnaire de secrets, jamais dans le code du navigateur, les binaires mobiles, les journaux ou le contrôle de source.
En-tête
Envoyez X-API-Key à chaque demande /v1.
Stockage
Stockez MEDIARUNTIME_API_KEY dans un gestionnaire de secrets côté serveur.
Rotation
Créez un remplacement, déployez-le, vérifiez le trafic, puis révoquez l'ancienne clé.
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3Laissez les métadonnées assurer l'intégration.
Le modèle de production utilisé par wMedia reste volontairement simple : soumettez une entrée, des recettes de sortie et suffisamment de métadonnées opaques pour rattacher l'événement terminal à votre propre enregistrement de base de données.
{
"source": "https://cdn.example.com/media/source.mp4",
"metadata": {
"producer": "my-api",
"entity_id": "video_01J8Y4",
"owner_id": "user_482",
"media_type": "video",
"trace_id": "req_f839"
},
"moderation": {
"enabled": true,
"mode": "report",
"checks": ["sexual", "violence", "dangerous"]
},
"watermark": { "enabled": true },
"outputs": [
{
"type": "mp4",
"preset": "mp4_720p_h264_aac",
"path_suffix": "web",
"poster_time_sec": 2,
"gif_preview": {
"enabled": true,
"width": 320,
"fps": 8,
"start_time": 2,
"duration": 2.5
}
},
{
"type": "image",
"preset": "image_multi_v1",
"path_suffix": "covers",
"images": [
{ "width": 1280, "height": 720, "mode": "fit", "format": "webp", "quality": 84 },
{ "width": 480, "height": 480, "mode": "cover", "format": "webp", "quality": 80 }
]
}
]
}| Champ | Tapez | Remarques |
|---|---|---|
| source | chaîne ou objet | Entrée unique canonique : une URL HTTP(S) publique, HTTP(S) signée et limitée dans le temps, gs:// accessible, ou un objet contenant uniquement url. |
| file_url | chaîne | Forme historique et durablement compatible du source scalaire. Ne combinez pas source et file_url. |
| inputs | tableau | Distribution par lots pour 1 à 25 entrées. Chaque élément utilise le source canonique ; l'ancien file_url reste pris en charge par élément. Ne combinez pas inputs avec l'un des champs d'entrée unique. |
| outputs | tableau | 1 à 10 recettes de sortie. Chacun nécessite type ; préréglage est fortement recommandé. |
| metadata | objet | Jusqu'à 32 Ko de JSON. Persistance et écho sur meta.request_metadata. |
| moderation | objet | Premium médias visuels contrôles : sexuel, violent, dangereux. |
| watermark | objet | Superposition de médias visuels Premium. Le compte doit déjà avoir un logo PNG. |
Distribution par lots
Utilisez un lot lorsque chaque entrée nécessite le même sorties. métadonnées par entrée est fusionné dans chaque tâche enfant ; le travail parent devient votre référence de lot.
{
"inputs": [
{
"source": "https://cdn.example.com/a.mp4",
"input_id": "asset-a",
"metadata": { "position": 0 }
},
{
"source": "https://cdn.example.com/b.mp4",
"input_id": "asset-b",
"metadata": { "position": 1 }
}
],
"metadata": { "batch_id": "import_2026_08_09" },
"outputs": [{ "type": "mp4", "preset": "mp4_720p_h264_aac" }]
}Nouvelles tentatives sécurisées avec Idempotency-Key
Une demande expirée est ambiguë : la tâche peut avoir été mise en file d'attente et seule la réponse a été perdue. Envoyez un en-tête Idempotency-Key et réessayez en toute sécurité : la même clé renvoie la tâche d'origine au lieu de la mettre en file d'attente et de facturer une seconde tâche. Sans l'en-tête, le comportement est inchangé et chaque POST crée une nouvelle tâche.
# One key per logical job. Generate it in your client, not inside the retry loop.
KEY=$(uuidgen) # or a deterministic id you can regenerate: asset_0426:mp4_720p:v1
curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY" \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "https://example.com/source.mp4",
"metadata": { "asset_id": "asset_0426" },
"outputs": [{ "type": "mp4", "preset": "mp4_720p_h264_aac" }]
}'
# Timed out? Send the exact same request again with the SAME key.
# You get the original job_id back - no second job, no second charge.Règles clés
- Un UUID fonctionne ; un identifiant déterministe comme
asset_0426:mp4_720p:v1est préférable, car vous pouvez le régénérer après un crash. - Les clés sont associées à votre compte et honorées pendant 24 heures.
- La réutilisation d’une clé avec un corps différent renvoie 422 – généralement une clé réutilisée dans une boucle.
- Une nouvelle tentative envoyée alors que la première est toujours en cours renvoie 409 ; réessayez après une courte pause.
- Soumettre volontairement le même fichier deux fois ? Utilisez deux clés différentes.
Choisissez l'artefact que vous souhaitez que le moteur produise.
Commencez par un alias de sortie figé pour les tâches courantes. Utilisez un `type` et un `preset` explicites lorsque vous devez personnaliser la recette ; les combinaisons incompatibles peuvent être refusées ou mal acheminées.
Alias de sortie figés
Les alias sont des contrats stables garantis par la passerelle. Ils sont résolus avant la validation, l'estimation, la facturation et la persistance, et peuvent être combinés avec des objets de sortie explicites dans le même tableau outputs.
| Alias | Résolution | Artefacts | Niveau |
|---|---|---|---|
| video.web | mp4 / mp4_720p_h264_aac, JPG poster at 2s | MP4 H.264/AAC 720p et affiche JPG | Standard |
| video.streaming | hls / hls_ladder_v1 | Manifeste HLS, variantes 1080p/720p et segments | Standard |
| video.social | social / social_vertical_blur | MP4 1080×1920 avec remplissage flouté 9:16 | Premium |
| audio.web | audio / audio_aac_128k | AAC/M4A à 128 kbps | Standard |
| audio.transcription | audio / audio_aac_128k with base subtitles | AAC/M4A avec sous-titres SRT et WebVTT | Standard |
| image.web | image / image_multi_v1 with two WebP renditions | Variantes WebP 1200×630 et 320×320 | Premium |
{
"source": "https://cdn.example.com/landscape-interview.mp4",
"outputs": ["video.social"]
}social_vertical_blur crée un H.264/AAC MP4 1080×1920. La source est mise à l'échelle pour s'adapter sans recadrage ; une copie floue remplit la toile 9:16 derrière elle. Utilisez-le pour les Reels, TikTok et les Shorts. Il s'agit d'une recette Premium car la sortie verticale a une hauteur de 1920 pixels.Fichiers vidéo et affiches
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| video_clip_v1 (type: mp4) | Vidéo | Effectue le rendu d’une plage précise en MP4 H.264/AAC, avec cadrage original ou vertical flouté et transcription fournie facultative. Standard, sans nouvelle transcription. clip.mp4, clip.srt and clip.vtt when transcript is supplied. | Standard |
| mp4_720p_h264_aac (type: mp4) | Vidéo | 720p H.264/AAC MP4 avec démarrage rapide pour la lecture Web. MP4 video. | Standard |
| mp4_ladder_v1 (type: mp4) | Vidéo | Trois rendus MP4 à 1080p, 720p et 480p, plus une affiche pour chaque rendu. 1080p MP4, 720p MP4, 480p MP4. | Standard |
| transmux_mp4_fast (type: mp4) | Vidéo | Copie les flux existants dans un faststart MP4 sans réencodage. Si la copie échoue et que le repli est activé, le moteur ré-encode avec le 720p H.264 préréglage. MP4 video. | Standard |
| poster_frame_v1 (type: mp4) | Vidéo | Un JPG 720p capturé à poster_time_sec. La requête type est toujours mp4. JPG poster. | Standard |
| mp4_hevc_1080p (type: mp4) | Vidéo | 1080p HEVC/H.265 + AAC MP4 avec la balise hvc1 pour la lecture Apple. HEVC MP4. | Premium |
| mp4_av1_smart (type: mp4) | Vidéo | 1080p AV1 + Opus MP4 optimisés pour l'efficacité de la compression ; l'encodage est gourmand en CPU. AV1 MP4. | Premium |
| mov_prores_422 (type: mp4) | Vidéo | Maître d'édition ProRes 422 HQ + PCM MOV. Préserve les dimensions de la source et produit un gros fichier mezzanine. ProRes MOV. | Premium |
Vidéo sociale
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| audiogram_v1 (type: social) | Audio ou vidéo avec audio | Compose un audio avec une illustration ajustée, une forme d’onde contrastée et des sous-titres facultatifs dans une zone sûre en MP4 social H.264/AAC Premium avec affiche propre. H.264/AAC audiogram MP4, caption-free poster JPEG, audiogram.json, audiogram.waveform.json. | Premium |
| social_vertical_blur (type: social) | Vidéo | 1080 × 1920 H.264/AAC MP4. Ajuste la source sur un arrière-plan flou de 9:16 pour les Reels, TikTok et Shorts. vertical MP4. | Premium |
GIF animé
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| gif_hq (type: gif) | Image ou vidéo | GIF animé à une largeur de 480 px et à 15 ips en utilisant la génération de palette pour une meilleure qualité de couleur. animated GIF. | Standard |
Extraction de trame
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| clip_candidates_v1 (type: frames) | Audio ou vidéo avec audio | Suggère des clips avec Whisper existant ou une transcription fournie, les limites de parole et les mots-clés. Analyse Premium ; le score ne prédit pas la viralité. clip_candidates.json with candidates and reusable source-timed transcript. | Premium |
| contact_sheet_v1 (type: frames) | Vidéo | Crée des planches-contact numérotées et contact_sheet.json, qui associe chaque vignette à son horodatage source. numbered contact-sheet images, contact_sheet.json. | Standard |
| extract_frames_1 (type: frames) | Vidéo | Séquence d'images numérotées JPG échantillonnée à 1 image par seconde. JPG frames at 1 fps. | Standard |
| extract_frames_5 (type: frames) | Vidéo | Séquence d'images numérotées JPG échantillonnée à 5 images par seconde. JPG frames at 5 fps. | Standard |
| scene_detect_v1 (type: frames) | Vidéo | Détecte les changements de plan et exporte une image clé JPG par plan, ainsi qu’un index scenes.txt avec horodatages et scores. scene JPGs, scene timeline. | Standard |
| perceptual_hash_v1 (type: frames) | Vidéo | Échantillonne la vidéo et écrit des empreintes perceptuelles de 64 bits dans phash.json pour détecter les republications et quasi-doublons. phash.json. | Standard |
Diffusion en continu
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| hls_ladder_v1 (type: hls) | Vidéo | Package HLS VOD avec variantes 1080p et 720p H.264/AAC, liste de lecture principale et segments de 6 secondes. HLS master playlist, variant playlists, media segments. | Standard |
| transmux_hls_fast (type: hls) | Vidéo | Copie les flux compatibles dans un package HLS sans réencodage. Avec le repli activé, les flux incompatibles sont encodés avec hls_ladder_v1. HLS master playlist, variant playlist, media segments. | Standard |
Streaming MPEG-DASH
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| dash_ladder_v1 (type: dash) | Vidéo | Package MPEG-DASH avec représentations H.264/AAC 1080p et 720p, manifest.mpd canonique et segments MP4 fragmentés. DASH MPD, initialization segments, media segments. | Standard |
| transmux_dash_fast (type: dash) | Vidéo | Copie les flux compatibles dans MPEG-DASH sans réencodage. Avec le repli activé, les flux incompatibles sont encodés avec dash_ladder_v1. DASH MPD, initialization segments, media segments. | Standard |
Vidéo WebM
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| webm_vp9_1080p (type: webm) | Vidéo | WebM VP9 + Opus 1080p pour les navigateurs modernes. Il s'agit d'un véritable encodage VP9, pas d'une étiquette MP4. VP9 WebM. | Premium |
Audio
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| audio_copy_fast (type: audio) | Audio ou vidéo avec audio | Copie le flux audio source sans réencodage. Si la copie échoue et que la restauration de secours est activée, le moteur écrit à la place AAC à 128 kbit/s. audio file. | Standard |
| audio_aac_128k (type: audio) | Audio ou vidéo avec audio | 128 kbps AAC dans un fichier M4A à démarrage rapide. M4A audio. | Standard |
| audio_mp3_128k (type: audio) | Audio ou vidéo avec audio | Fichier MP3 de 128 kbit/s. MP3 audio. | Standard |
| audio_opus_96k (type: audio) | Audio ou vidéo avec audio | Fichier Opus de 96 kbps, bien adapté à la transmission vocale. Opus audio. | Standard |
| audio_loudnorm_aac_128k (type: audio) | Audio ou vidéo avec audio | Normalise vers -16 LUFS, puis écrit 128 kbps AAC. normalized M4A audio, loudness metrics. | Standard |
| audio_trim_silence_aac_128k (type: audio) | Audio ou vidéo avec audio | Supprime les silences de début et de fin, puis écrit AAC à 128 kbit/s. trimmed M4A audio. | Premium |
| audio_loudnorm_trim_aac_128k (type: audio) | Audio ou vidéo avec audio | Coupe le silence des limites, normalise vers -16 LUFS, puis écrit 128 kbps AAC. trimmed and normalized M4A audio, loudness metrics. | Premium |
| audio_whisper_prep (type: audio) | Audio ou vidéo avec audio | PCM mono 16 kHz WAV préparé pour Whisper, ASR ou d'autres pipelines vocaux. WAV audio. | Standard |
Dérivés d'images
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| image_multi_v1 (type: image) | Image ou vidéo | Crée les images demandées avec fit, fill, cover ou contain. Les rendus JPG et WebP peuvent définir max_bytes comme plafond strict vérifié et recevoir image_size_limits.json. Le niveau dépend du format, de la taille, du nombre, du recadrage intelligent et de la suppression de l’arrière-plan. image renditions, image_size_limits.json when max_bytes is used, smart_crop.json when enabled. | Standard |
| image_animated_webp_v1 (type: image) | Vidéo | Crée un WebP animé borné depuis une vidéo avec largeur, fréquence, début, durée, qualité et répétitions configurables. animated WebP. | Premium |
| image_animated_apng_v1 (type: image) | Vidéo | Crée un PNG animé sans perte depuis une vidéo avec largeur, fréquence, début, durée et répétitions configurables. animated PNG. | Premium |
| image_placeholders_v1 (type: image) | Image ou vidéo | Crée BlurHash et ThumbHash conformes, la géométrie source et substitut, une couleur dominante tenant compte de l’alpha et un LQIP WebP limité en octets depuis une image ou une image vidéo. placeholders.json, lqip.webp. | Standard |
Analyse et rapports
| Préréglage | Envoyer | Exécution du travail | Niveau de base |
|---|---|---|---|
| compatibility_report_v1 (type: image) | Vidéo | Évalue la vidéo selon cinq profils versionnés web, mobile, import social et montage, avec preuves par règle et presets correctifs. compatibility_report.json. | Standard |
| media_report_v1 (type: image) | Audio, image ou vidéo | Inspecte les métadonnées audio, vidéo ou image sans transcodage et écrit media_report.json avec les détails du conteneur et des flux, ainsi que le GOP, l’EXIF et le GPS lorsqu’ils sont présents. media_report.json. | Standard |
| code_detect_v1 (type: frames) | Image ou vidéo | Analyse une fenêtre initiale limitée pour détecter les QR codes et codes-barres dans les images, vidéos, animations et pochettes audio intégrées ; produit codes.json et les images de preuve lorsqu’un code est trouvé. codes.json, evidence frames when codes are found. | Standard |
transmux_*_fast évitent un encodage qui change la qualité lorsque les flux sont compatibles avec MP4, HLS ou DASH. Si la copie échoue et que le repli est activé, le moteur utilise le preset encodé correspondant.Utilisez une seule source. Produisez les formats et les artefacts side-car dont votre produit a besoin.
L'extension source ne sélectionne pas la sortie. Les type et préréglage choisissent la recette exécutable, de sorte qu'une vidéo téléchargée peut devenir une vidéo de lecture, un média audio uniquement, des transcriptions, des aperçus GIF, des affiches ou des séquences d'images dans la même tâche asynchrone.
| Origine | Livrable | Recette |
|---|---|---|
| JPG, PNG ou WebP | JPG, PNG, WebP ou dérivés AVIF | image + image_multi_v1 ; choisissez images[].format, les dimensions, mode et quality. JPG/WebP accepte max_bytes et min_quality pour un plafond strict vérifié. |
| Vidéo | Web MP4, HLS, vidéo sociale ou maître de montage | Choisissez le mp4, hls ou social préréglage correspondant. |
| Vidéo | Séquence d'images animée GIF, affiche ou JPG | Utilisez gif_hq, poster_frame_v1, extract_frames_1/5 ou connectez gif_preview à une sortie vidéo. |
| Vidéo ou audio | M4A, MP3, Opus ou parole WAV | Choisissez l'audio_* préréglage correspondant ; la vidéo entrées voit son flux audio extrait. |
| Discours vidéo ou audio | SRT, WebVTT ou les deux | Ajoutez des sous-titres à une sortie audio ou vidéo et choisissez srt, vtt ou les deux. |
{
"source": "https://cdn.example.com/media/product-photo.png",
"metadata": {
"media_type": "image",
"asset_id": "product-photo-0426"
},
"outputs": [{
"type": "image",
"preset": "image_multi_v1",
"path_suffix": "converted",
"images": [
{ "width": 1600, "height": 1200, "mode": "fit", "format": "jpg", "quality": 88 },
{ "width": 1600, "height": 1200, "mode": "fit", "format": "webp", "quality": 82 }
]
}]
}{
"source": "https://cdn.example.com/media/interview.mov",
"outputs": [
{ "type": "mp4", "preset": "mp4_720p_h264_aac", "path_suffix": "web-video" },
{ "type": "audio", "preset": "audio_mp3_128k", "path_suffix": "audio-only" }
]
}{
"source": "https://cdn.example.com/media/interview.mp4",
"metadata": { "media_type": "video", "asset_id": "interview-0426" },
"outputs": [{
"type": "audio",
"preset": "audio_aac_128k",
"path_suffix": "audio-and-transcript",
"subtitles": {
"enabled": true,
"languages": ["auto"],
"format": "both",
"model": "ggml-base.bin",
"translate_to_english": false
}
}]
}{
"source": "https://cdn.example.com/media/trailer.mp4",
"metadata": { "media_type": "video", "asset_id": "trailer-0426" },
"outputs": [{
"type": "mp4",
"preset": "mp4_720p_h264_aac",
"path_suffix": "web",
"poster_time_sec": 4,
"poster_format": "jpg",
"gif_preview": {
"enabled": true,
"width": 480,
"fps": 10,
"start_time": 4,
"duration": 3
}
}]
}{
"source": "https://cdn.example.com/media/feature-film.mp4",
"metadata": { "media_type": "video", "asset_id": "stream-0426" },
"outputs": [{
"type": "hls",
"preset": "hls_ladder_v1",
"path_suffix": "stream"
}]
}{
"source": "https://cdn.example.com/media/clip.mp4",
"metadata": { "media_type": "video", "asset_id": "clip-0426" },
"outputs": [
{ "type": "gif", "preset": "gif_hq", "path_suffix": "animated-preview" },
{ "type": "frames", "preset": "extract_frames_1", "path_suffix": "sampled-frames" }
]
}hls_ladder_v1 crée une liste de lecture principale, des listes de lecture de variantes H.264/AAC 1080p et 720p et des segments multimédias de 6 secondes. Utilisez la liste de lecture principale URL signalée ou déplacez l'ensemble complet ensemble.gif_hq crée un GIF principal complet de 480 pixels, 15 ips. gif_preview ajoute un GIF plus court et explicitement chronométré à une autre sortie vidéo. Les préréglages d’images renvoient des séquences JPG numérotées à une ou cinq images par seconde.Commutateurs utiles
audio_aac_128k renvoie M4A, audio_mp3_128k renvoie MP3, audio_opus_96k renvoie Opus et audio_whisper_prep renvoie 16 kHz mono WAV. Définissez subtitles.format sur srt, vtt ou both. Pour une seule image d'affiche, envoyez type: mp4 avec preset: poster_frame_v1 et le poster_time_sec souhaité.
Analyser, vérifier et produire des clips
Utilisez video_clip_v1 pour une plage précise, ou clip_candidates_v1 pour suggérer des passages. Les deux utilisent l’API de tâches asynchrones.
Le découpage manuel ne nécessite aucun modèle
video_clip_v1 utilise type: mp4 et le traitement Standard. Début fini ≥ 0, durée de 0.1–300 secondes, plage entièrement dans la source. original conserve les proportions avec un grand côté de 1920 px maximum et 30 fps ; vertical_blur utilise 720 × 1280 à 30 fps maximum. Le rendu, y compris l’incrustation de sous-titres fournis, n’exécute jamais Whisper.
{
"source": "https://cdn.example.com/interview.mp4",
"outputs": [{
"type": "mp4",
"preset": "video_clip_v1",
"clip": {
"start_time_sec": 0,
"duration_sec": 30,
"layout": "original",
"burn_captions": false
}
}]
}Analyse facultative des candidats
clip_candidates_v1 utilise type: frames et Premium, même avec un texte fourni. Si clip_analysis.transcript est absent ou vide, Whisper est exécuté ; une transcription non vide l’évite. L’envoi de texte est facultatif. Durées minimale/maximale : 1–300 secondes ; max_candidates : 1–20. Le minimum ne doit dépasser ni le maximum ni la durée exacte de la source. Une seule analyse par tâche ; source limitée à six heures. Les scores évaluent les limites de parole et mots-clés, pas la viralité.
{
"source": "https://cdn.example.com/interview.mp4",
"outputs": [{
"type": "frames",
"preset": "clip_candidates_v1",
"clip_analysis": {
"min_duration_sec": 15,
"max_duration_sec": 60,
"max_candidates": 5,
"keywords": ["deployment"]
}
}]
}Vérifier avant le rendu
Après COMPLETED, GET /v1/jobs/{job_id}/clip-candidates renvoie la transcription et les plages modifiables. L’analyse produit clip_candidates.json, pas une vidéo ou du JavaScript. Soumettez les plages dans une nouvelle tâche video_clip_v1 avec la même source. Un tableau candidates vide est valide : empty_reason vaut no_speech, no_keyword_match, no_matching_ranges ou source_too_short (réservé aux lecteurs de rapports). Avec des candidats, il vaut null ; les anciens rapports peuvent l’omettre. Réutilisez une transcription non vide même sans suggestion.
Joindre et incruster des sous-titres datés sur la source
REST/Python utilise clip.transcript avec {start_time_sec, end_time_sec, text} ; le SDK Node utilise {startTimeSec, endTimeSec, text}. Fournissez des tableaux de segments, pas des URL de fichiers. Gardez les temps de la source complète ; le moteur découpe et recale les segments. burn_captions: true exige du texte chevauchant le clip. Studio accepte SRT, VTT ou JSON (≤ 1 MiB), localement ou dans le cloud ; la sélection dans la liste joint immédiatement le fichier. Une transcription valide chevauchante active la case. Sandbox anonyme accepte les fichiers locaux ; le cloud exige une connexion. La transcription d’analyse se joint dans l’option de réutilisation. Le ZIP contient MP4, affiche et les SRT/VTT correspondants.
{
"source": "https://cdn.example.com/interview.mp4",
"outputs": [{
"type": "mp4",
"preset": "video_clip_v1",
"clip": {
"start_time_sec": 20,
"duration_sec": 15,
"layout": "vertical_blur",
"burn_captions": true,
"transcript": [
{"start_time_sec": 20, "end_time_sec": 35, "text": "Example speech."}
]
}
}]
}Limites et disponibilité
Transcriptions : ≤ 2,000 segments, ≤ 2,000 octets UTF-8 par segment, ≤ 256 KiB de texte ; débuts finis ordonnés, fin > début, dans la source. Mots-clés : ≤ 20, ≤ 100 octets UTF-8 chacun. Contrôles combinés : ≤ 512 KiB. Le rendu refuse les options subtitles, watermark et les réglages indépendants incompatibles. L’estimation acceptée détermine le niveau final. Sandbox public accepte les exemples configurés et Standard ; l’analyse Premium nécessite un Workspace éligible.
Préparation des SDK et CLI 1.4.0
Ces exemples nécessitent la publication et l’installation des paquets 1.4.0 correspondants ; la publication reste en attente. Node expose jobs.getClipCandidates() et emptyReason ; Python, jobs.get_clip_candidates() et empty_reason. La CLI accepte SRT, VTT et JSON locaux via --clip-transcript (≤ 1 MiB). Un clip manuel sans ce paramètre ni --clip-captions ne nécessite aucune transcription.
# Automatic transcription and candidate suggestions (Premium).
mediaruntime run ./interview.mp4 --preset clip_candidates_v1 \
--clip-min-duration 15 --clip-max-duration 60 --clip-count 5 \
--clip-keyword deployment --download ./analysis.zip
# Inspect clip_candidates.json in the downloaded ZIP and choose a range.
# A supplied source-timed transcript burns captions without invoking Whisper.
mediaruntime run ./interview.mp4 --preset video_clip_v1 \
--clip-start 20 --clip-duration 15 --clip-layout vertical_blur \
--clip-transcript ./source.srt --clip-captions --download ./clip.zip
# Manual clipping without captions or any transcription model.
mediaruntime run ./interview.mp4 --preset video_clip_v1 \
--clip-start 0 --clip-duration 10 --download ./manual.zipimport { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime({ apiKey: process.env.MEDIARUNTIME_API_KEY });
// Retain this stable source reference with the plan. Do not save an expiring URL.
const source = "https://your-cdn.example/episode.mp4";
const analysis = await media.jobs.create({ source, outputs: [{
type: "frames", preset: "clip_candidates_v1",
clipAnalysis: { minDurationSec: 15, maxDurationSec: 60, maxCandidates: 5 },
}] });
const analyzed = await analysis.wait();
if (analyzed.status !== "COMPLETED") throw new Error(`Analysis ${analyzed.status}`);
const plan = await media.jobs.getClipCandidates(analysis.id);
// Present candidates for human review. A score is a heuristic, not predicted engagement.
const selected = plan.candidates[0];
if (!selected) {
console.log("No suggestions:", plan.emptyReason ?? "No reason in this older report");
// Stop this automatic render path; plan.transcript remains usable for manual clips.
process.exit(0);
}
const render = await media.jobs.create({ source, outputs: [{
type: "mp4", preset: "video_clip_v1", clip: {
startTimeSec: selected.startTimeSec,
durationSec: selected.durationSec,
layout: "vertical_blur", // or original
burnCaptions: true,
// Keep SOURCE timestamps. The engine intersects and rebases cues for this render.
transcript: plan.transcript.filter((segment) =>
segment.endTimeSec > selected.startTimeSec &&
segment.startTimeSec < selected.startTimeSec + selected.durationSec),
},
}] });
const rendered = await render.wait();
if (rendered.status !== "COMPLETED") throw new Error(`Render ${rendered.status}`);
console.log(rendered.bundle.downloadUrl); // Short-lived URL for the complete ZIP.Commencez avec un préréglage ; ignorer uniquement ce qui compte.
Les préréglages maintiennent les requêtes lisibles et donnent au moteur une base de référence stable. Ajoutez des options de rendu explicite, de sous-titres, d'aperçu, de codec ou de débit uniquement lorsque le produit l'exige.
Web MP4
- Source
- Video with a decodable video stream; audio is optional
- Artifacts
- 720p H.264/AAC MP4 and a JPG poster
// Source: Video with a decodable video stream; audio is optional
// Alias: video.web
// Preset: mp4_720p_h264_aac
// Artifacts: 720p H.264/AAC MP4 and a JPG poster
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/source.mov",
"metadata": {
"asset_id": "asset_0426",
"recipe": "web-mp4"
},
"outputs": [
"video.web"
],
"idempotencyKey": "asset:web-mp4:v1"
});
console.log(job.id, job.status);HLS streaming
- Source
- Video with a decodable video stream; audio is optional
- Artifacts
- Master playlist, 1080p/720p variants, and six-second media segments
// Source: Video with a decodable video stream; audio is optional
// Alias: video.streaming
// Preset: hls_ladder_v1
// Artifacts: Master playlist, 1080p/720p variants, and six-second media segments
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/feature.mp4",
"metadata": {
"asset_id": "asset_0426",
"recipe": "hls-streaming"
},
"outputs": [
"video.streaming"
],
"idempotencyKey": "asset:hls:v1"
});
console.log(job.id, job.status);Vertical social video
- Source
- Landscape, square, or portrait video
- Artifacts
- 1080×1920 H.264/AAC MP4 with a blurred 9:16 fill
// Source: Landscape, square, or portrait video
// Alias: video.social
// Preset: social_vertical_blur
// Artifacts: 1080×1920 H.264/AAC MP4 with a blurred 9:16 fill
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/interview.mp4",
"metadata": {
"asset_id": "asset_0426",
"recipe": "vertical-social"
},
"outputs": [
"video.social"
],
"idempotencyKey": "asset:social:v1"
});
console.log(job.id, job.status);Responsive image derivatives
- Source
- JPG, PNG, WebP, or another supported still image
- Artifacts
- 1200×630 and 320×320 metadata-stripped WebP renditions
// Source: JPG, PNG, WebP, or another supported still image
// Alias: image.web
// Preset: image_multi_v1
// Artifacts: 1200×630 and 320×320 metadata-stripped WebP renditions
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/product.png",
"metadata": {
"asset_id": "asset_0426",
"recipe": "image-derivatives"
},
"outputs": [
"image.web"
],
"idempotencyKey": "asset:image-derivatives:v1"
});
console.log(job.id, job.status);Audio plus transcript
- Source
- Audio, or video containing a decodable audio stream
- Artifacts
- 128 kbps AAC/M4A plus SRT and WebVTT transcripts
// Source: Audio, or video containing a decodable audio stream
// Alias: audio.transcription
// Preset: audio_aac_128k
// Artifacts: 128 kbps AAC/M4A plus SRT and WebVTT transcripts
// Tier: Standard
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/interview.mp4",
"metadata": {
"asset_id": "asset_0426",
"recipe": "audio-transcript"
},
"outputs": [
"audio.transcription"
],
"idempotencyKey": "asset:audio-transcript:v1"
});
console.log(job.id, job.status);Moderation plus watermarking
- Source
- One image or video; this example uses video
- Artifacts
- Watermarked 720p MP4, JPG poster, and moderation evidence report
// Source: One image or video; this example uses video
// Alias: video.web
// Preset: mp4_720p_h264_aac
// Artifacts: Watermarked 720p MP4, JPG poster, and moderation evidence report
// Tier: Premium
// Testing: use job.wait(); production: persist job.id and consume the signed webhook
// npm install @mediaruntime/node
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const job = await media.jobs.create({
"source": "https://cdn.example.com/media/upload.mp4",
"metadata": {
"asset_id": "asset_0426",
"recipe": "moderation-watermark"
},
"moderation": {
"enabled": true,
"mode": "report",
"checks": [
"sexual",
"violence",
"dangerous"
]
},
"watermark": {
"enabled": true
},
"outputs": [
"video.web"
],
"idempotencyKey": "asset:moderation-watermark:v1"
});
console.log(job.id, job.status);{ "watermark": { "enabled": true } } ; MediaRuntime résout le logo appartenant au serveur.Versionnez la politique complète, pas des copies de JSON de requête.
Les recettes hébergées sont des versions immuables propres au compte pour outputs, moderation et watermark. Utilisez le nom pour la dernière version active ou `name@version` lorsqu’un déploiement ne doit jamais changer.
# Discover the built-in and account recipes available to this key.
mediaruntime recipes list
# A hosted recipe may be pinned to one immutable version.
mediaruntime run ./launch.mp4 \
--recipe team-video@3 \
--download ./launch.zip
# The raw API accepts the same reference.
curl -sS -X POST "https://mediaruntime.com/v1/jobs" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "https://cdn.example.com/media/launch.mp4",
"recipe": "web-video@1",
"metadata": { "asset_id": "launch-01" }
}'recipe et le même SHA-256.web-video@1, social-video@1 et ai-transcription@1.Ajoutez une analyse de sécurité visuelle à plusieurs niveaux au travail.
La modération utilise un pipeline en couches pour une image ou une vidéo. Le mode report renvoie les preuves et poursuit le traitement. Le mode block est une barrière fail-closed avant le moteur : block ou review rejette le travail, tandis que allow continue.
{
"source": "https://cdn.example.com/upload.mp4",
"metadata": { "media_type": "video", "asset_id": "asset_0426" },
"moderation": {
"enabled": true,
"mode": "report",
"checks": ["sexual", "violence", "dangerous"]
},
"outputs": [{
"type": "mp4",
"preset": "mp4_720p_h264_aac"
}]
}{
"moderation": {
"requested": {
"enabled": true,
"mode": "report",
"checks": ["sexual", "violence", "dangerous"],
"media_type": "video",
"phase": "phase1_video_report"
},
"result": {
"ok": true,
"media_type": "video",
"verdict": "review",
"flagged_checks": ["violence"],
"scores": {
"violence": { "yes": 0.82, "no": 0.18 }
},
"decisions": {
"violence": { "decision": "review", "raw_decision": "review" }
},
"evidence": {
"frames_sampled": 8,
"frames_flagged": [{
"frame_index": 3,
"timestamp_sec": 20,
"verdict": "review",
"flagged_checks": ["violence"]
}]
},
"video": {
"frame_interval_sec": 10,
"max_frames": 24
}
}
},
"meta": {
"moderation_result": {
"url": "https://storage.googleapis.com/.../moderation_result.json"
}
},
"usage": {
"breakdown": { "moderation_units": 120 }
}
}| Contrat | Valeur | Remarques |
|---|---|---|
| Planifier | Premium | Le API renvoie 403, sauf si le compte est Premium ou si la mise à niveau automatique est autorisée. |
| Mode | report ou block | report est observationnel ; block rejette les verdicts block/review avant le démarrage du moteur. |
| Chèques | sexuel, violence, dangereux | Envoyez un à trois contrôles. L’omission de contrôles sélectionne les trois. |
| Entrées | Une image ou une vidéo | Les entrées audio seules, les lots et la modération dans le Sandbox sont refusés. |
| Échantillonnage vidéo | Intervalle fixe, images délimitées | Le service choisit l'intervalle et le plafond ; lisez les valeurs réelles de result.video et result.evidence. |
| Décision | autoriser, examiner ou bloquer le signal | report ne bloque jamais l'exécution. block est fail-closed : allow continue ; review ou block se termine par REJECTED. |
| Artefact | méta/moderation_result.json | Inclus dans le ZIP de sortie et exposé via meta.moderation_result.url lorsqu'il est disponible. |
| Facturation | Par trame analysée | Une inférence par image : une image correspond à 1 image, une vidéo est échantillonnée jusqu'à une limite de 24. Réglé à partir de result.evidence.frames_sampled à usage.breakdown.moderation_units. |
| Autonome | sorties est peut-être vide | Envoyez `outputs: []` pour modérer un fichier sans le transcoder. Seule la modération est facturée. |
report lorsque votre application prend la décision de publication. Utilisez block pour rejeter avant le transcodage ; un travail rejeté n'a pas de bundle de sortie et ne facture que les unités de modération.Vérifiez les octets bruts avant de faire confiance à l'événement.
Les événements de terminal sont livrés au moins une fois et la commande n'est pas garantie. Vérifiez HMAC-SHA256, rejetez les horodatages obsolètes, dédupliquez event_id, accusez réception rapidement et déplacez les travaux lourds vers une file d'attente.
{
"event_id": "webhook_evt_job_1320c28b72104811b075a26a99496cf6",
"job_id": "job_1320c28b72104811b075a26a99496cf6",
"account_id": "acc_xxx",
"status": "COMPLETED",
"completedAt": "2026-08-09T02:41:23Z",
"billing": { "status": "PAID", "estimatedUnits": 31 },
"usage": { "units_total": 31, "breakdown": {} },
"delivery": {
"mode": "PULL",
"retentionDays": 7,
"expiresAt": "2026-08-16T02:41:23Z",
"bundle": {
"type": "zip",
"filename": "outputs.zip",
"download": {
"url": "https://mediaruntime.com/v1/jobs/job_1320c28b72104811b075a26a99496cf6/bundle?token=...",
"expiresAt": "2026-08-16T02:41:23Z"
}
}
},
"meta": {
"engine_result_url": "https://storage.googleapis.com/...",
"outputs_root_gs": "gs://.../jobs/acc_xxx/job_.../outputs",
"request_metadata": {
"producer": "my-api",
"entity_id": "video_01J8Y4",
"media_type": "video"
}
}
}delivery.bundle.download.url ou récupérez meta.engine_result_url pour énumérer les chemins de sortie et d'artefact individuels.import express from "express";
import { MediaRuntime } from "@mediaruntime/node";
const media = new MediaRuntime();
const app = express();
// Register this route before any express.json() middleware.
app.post(
"/webhooks/mediaruntime",
express.raw({ type: "application/json" }),
media.webhooks.express(async (event, _req, res) => {
// Persist and deduplicate event.id before acknowledging.
console.log(event.id, event.jobId, event.status);
res.sendStatus(204);
}),
);Règles de livraison
- Renvoyez les 2xx uniquement après vérification de la signature et mise en file d'attente/déduplication durable.
- Traitez event_id comme la clé de l’idempotence.
- Utilisez meta.request_metadata pour trouver votre entité sans deuxième table de recherche.
- Téléchargement conservé sorties avant delivery.expiresAt.
- Un événement FAILED ou REJECTED a error.code/message et aucun bundle utilisable. Un lot PARTIAL a error.code BATCH_PARTIAL ; consultez delivery.items pour l'état de chaque tâche enfant et les bundles réussis.
Sondez lorsqu’un webhook n’est pas pratique.
La soumission revient immédiatement avec un job_id. Les webhooks restent le moyen avec la latence la plus faible pour apprendre qu'une tâche est terminée, mais des sondages sont disponibles pour le développement local, les environnements sans point de terminaison public, la réconciliation et les questions d'assistance.
curl -sS "https://mediaruntime.com/v1/jobs/$JOB_ID" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY"# Newest first. Filter by status and page with the cursor.
curl -sS "https://mediaruntime.com/v1/jobs?status=COMPLETED&limit=25" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY"
# Next page: pass the previous response's next_cursor
curl -sS "https://mediaruntime.com/v1/jobs?limit=25&cursor=$NEXT_CURSOR" \
-H "X-API-Key: $MEDIARUNTIME_API_KEY"{
"job_id": "job_2ee8db582cdf4a2fafb49d52218b3159",
"status": "COMPLETED",
"tier": {
"requested": "premium",
"required": "standard",
"effective": "premium",
"billed": "standard",
"reasons": []
},
"usage": { "units_total": 4 },
"billing": {
"status": "PAID",
"currency": "USD",
"unit_price_cents": 1,
"final_units": 4,
"final_amount_cents": 4
},
"bundle": {
"available": true,
"download_url": "https://mediaruntime.com/v1/jobs/job_2ee8.../bundle?token=...",
"expires_at": "2026-08-18T03:14:27Z",
"size_bytes": 13056793,
"retention_days": 7
},
"media": {
"format": "mov,mp4,m4a,3gp,3g2,mj2",
"duration_sec": 61.5,
"bit_rate": 8000000,
"video": {
"codec": "h264",
"profile": "High",
"width": 1080,
"height": 1920,
"encoded_width": 1920,
"encoded_height": 1080,
"fps": 29.97,
"rotation_deg": 90,
"is_rotated": true,
"orientation": "portrait"
},
"audio": { "codec": "aac", "sample_rate_hz": 48000, "channels": 2, "layout": "stereo" },
"streams": { "video": 1, "audio": 1, "other": 0 }
},
"metadata": { "asset_id": "asset_0426", "media_type": "video" },
"error": null,
"completed_at": "2026-08-11T03:14:53Z"
}requested est le niveau de la clé API qui a soumis le travail. required est ce dont le travail a réellement besoin, effective est la voie sur laquelle il s'est déroulé et billed est ce qui vous a été facturé. Une clé premium exécutant un travail standard montre requested: premium avec billed: standard — vous êtes facturé pour le travail, pas pour la clé.media rapporte ce que MediaRuntime a trouvé dans votre entrée lorsqu'il l'a sondé lors de la soumission - la même sonde qui décide si une tâche est acceptée. Lorsqu'une tâche est REJETÉE pour un appariement incompatible, cela explique pourquoi : un MP3 envoyé vers une sortie d'image affiche streams.video: 0, et une image fixe envoyée vers une sortie d'images n'a pas de duration_sec. Remarque : video.width/height sont des dimensions d'AFFICHAGE avec rotation appliquée, donc un clip de téléphone en mode portrait indique 1 080 x 1 920 même si les encoded_width/encoded_height sont en 1 920 x 1 080. Chaque champ est facultatif : un champ manquant signifie que la sonde ne l'a pas signalé, jamais zéro.GET /v1/jobs/{job_id}/moderation renvoie uniquement le verdict, afin qu'un client qui interroge l'API pour prendre une décision ne récupère pas à chaque fois les détails de facturation et du bundle. La réponse contient verdict, decision et confidence pour chaque contrôle, ainsi que les likelihoods d'escalade. Un contrôle marqué review_only est consultatif : il peut produire un verdict review, mais ne peut pas bloquer seul. L'endpoint renvoie **404 lorsque la tâche existe mais que la modération n'a jamais été demandée** ; une réponse vide réussie serait impossible à distinguer d'une tâche modérée sans résultat. Les seuils de décision ne sont pas publiés.GET /v1/jobs/{job_id}/media-report renvoie le document media_report_v1 sans télécharger le bundle. report le transporte en ligne ; un rapport inhabituellement volumineux n'est pas stocké en ligne et la réponse définit ensuite report sur null avec un download_url qui est toujours résolu, donc gérez les deux. Renvoie 404 lorsque le travail ne contient aucun rapport.GET /v1/jobs/{job_id}/compatibility-report renvoie le document versionné compatibility_report_v1 sans télécharger le ZIP. Il contient cinq profils conservateurs, des preuves par règle et un preset correctif pour les profils incompatibles. Il s'agit d'un guide pratique, pas d'une certification exhaustive des appareils. Gérez report ou download_url ; l'endpoint renvoie 404 si le preset n'a pas été demandé.GET /v1/jobs/{job_id}/codes renvoie l’analyse limitée de code_detect_v1 sans télécharger le ZIP. Les images, vidéos, animations et fichiers audio avec pochette intégrée sont acceptés ; un audio sans image reçoit une erreur explicative. L’analyse conserve au maximum 12 images échantillonnées et 16 codes uniques par image. Traitez chaque decoded_text comme du texte non fiable : ne le rendez jamais en HTML et n’ouvrez jamais automatiquement une URL décodée. Les images de preuve sont référencées par leur chemin dans le bundle.| Champ | Tapez | Remarques |
|---|---|---|
| statut | chaîne | QUEUED, PROCESSING, COMPLETED, FAILED, REJECTED ou PARTIAL pour les lots uniquement. |
| niveau | objet | demandé / requis / effectif / facturé, ainsi que les raisons pour lesquelles la prime était requise. |
| utilisation.units_total | entier | Unités facturables pour le travail. |
| facturation | objet | Devise, prix unitaire, unités et montants estimés par rapport aux unités finales. |
| bundle.download_url | chaîne | Offre groupée URL expirant et limitée à la tâche. Point de terminaison à tâche unique uniquement. |
| médias | objet | Quelle était réellement la contribution, comme sondé lors de la soumission. Nul sur les emplois plus anciens. |
| media.video.largeur/hauteur | entier | Afficher les dimensions, rotation déjà appliquée. |
| médias.duration_sec | numéro | Absent pour les images fixes, qui n’ont pas de chronologie. |
| metadata | objet | L'objet métadonnées que vous avez soumis a été renvoyé. |
| erreur | chaîne | Renseigné pour FAILED, REJECTED ou PARTIAL pour les lots uniquement ; null sinon. |
Règles de sondage
- Préférez les webhooks ; sondage uniquement lorsque vous ne pouvez pas en recevoir un.
- Page avec next_cursor, jamais de décalage : les lignes se déplacent à mesure que les tâches sont mises à jour.
- Un identifiant de travail que vous ne possédez pas renvoie 404, le même qu'un identifiant qui n'existe pas.
- Les lignes de la liste omettent le bundle URL ; récupérez le travail unique à télécharger.
- Reculez entre les sondages. Le statut d'un terminal ne changera pas.
Prépayé, payé au fur et à mesure et réglé à partir de l'utilisation réelle.
Ajoutez une carte, approvisionnez le portefeuille et soumettez votre travail sans abonnement récurrent. MediaRuntime réserve une estimation avant l'exécution et règle les frais finaux lorsque le travail atteint un état terminal.
| Planifier | Prix d'utilisation de départ | Recharge minimale | Recharge automatique par défaut |
|---|---|---|---|
| Standard Pay-As-You-Go | De $0.02 | $5.00 | $5.00 à $2.00 disponible |
| Premium Pay-As-You-Go | De $0.05 | $20.00 | $20.00 à $5.00 disponible |
billing et usage pour le rapprochement.Règles du portefeuille
- Le crédit disponible est égal au crédit du portefeuille moins les fonds réservés à l'exécution des tâches.
- Un crédit disponible insuffisant renvoie HTTP 402 avant exécution.
- Le rechargement automatique est facultatif et nécessite une carte enregistrée.
- Une requête Premium uniquement renvoie 403 lorsque la mise à niveau n'est pas autorisée.
Réessayez les échecs de transport, pas le travail invalide.
Chaque réponse inclut X-Request-Id. Les erreurs ajoutent un objet error normalisé tout en conservant detail/message pour compatibilité. Journalisez l’ID de requête, le code et le statut, mais jamais la clé API, les URL signées ou le corps de la requête.
| Statut | Code | Signification | Ce que votre intégration devrait faire |
|---|---|---|---|
| 400 | invalid_request | La demande est logiquement invalide ou l'estimateur l'a rejetée. | Corrigez la demande ; ne réessayez pas inchangé. |
| 401 | authentication_error | La clé API n'est pas valide, a expiré ou est révoquée. | Corrigez ou faites pivoter la clé ; ne réessayez pas aveuglément. |
| 402 | billing_required | Le compte, le portefeuille ou le contrôle préalable de facturation ne peuvent pas couvrir le travail. | Financez le portefeuille ou résolvez d’abord la facturation. |
| 403 | permission_denied | Le plan, le rôle ou la porte de fonctionnalité n'autorise pas la demande. | Changer le plan/la demande ; ne réessayez pas inchangé. |
| 404 | not_found | La ressource détenue est absente ou masquée par la portée du propriétaire. | Corrigez l’identifiant ; ne réessayez pas sans modification. |
| 409 | idempotency_in_progress / conflict | Une opération avec cette clé est en cours ou entre en conflit avec une opération active. | Réessayez uniquement lorsque error.retryable vaut true. |
| 410 | gone | Un jeton de courte durée a expiré. | Obtenez un nouveau résultat ou jeton. |
| 413 | request_too_large | Le corps de la requête HTTP dépasse 2 Mio. | Téléchargez les médias séparément et envoyez uniquement les URL. |
| 422 | validation_error / idempotency_conflict / unprocessable_entity | La validation a échoué ou une clé d’idempotence a été réutilisée avec un autre corps. | Corrigez le champ ou la clé indiqué. |
| 429 | rate_limited | Le compte ou la clé est à débit limité. | Réessayez avec un recul exponentiel et une gigue. |
| 500 | internal_error | La passerelle a échoué de manière inattendue. | Réessayez en toute sécurité avec temporisation. |
| 502 | upstream_error | Une dépendance transitoire de la plateforme a échoué. | Réessayez en toute sécurité avec temporisation. |
| 503 | service_unavailable | Une dépendance ou une voie d’exécution est indisponible. | Réessayez en toute sécurité avec temporisation. |
{
"error": {
"code": "billing_required",
"message": "Insufficient wallet balance for this job",
"status": 402,
"retryable": false,
"request_id": "req_7fa01eec9b6248a5a7be2d60ff4bb978",
"details": null
},
"request_id": "req_7fa01eec9b6248a5a7be2d60ff4bb978",
"detail": "Insufficient wallet balance for this job"
}La petite surface dont la plupart des intégrations ont besoin.
Tous les points de terminaison de serveur à serveur ci-dessous utilisent X-API-Key. Le bundle tokenisé URL est la seule exception car il comporte son propre identifiant de courte durée, limité à l'emploi.
| Méthode | Chemin | Objectif |
|---|---|---|
| POSTER | /v1/upload-url | Créez éventuellement une cible de téléchargement de 15 minutes lorsque vous ne disposez pas déjà d'un média récupérable URL. |
| POSTER | /v1/jobs | Mettez en file d'attente une tâche multimédia à entrée unique ou par lots. |
| OBTENIR | /v1/jobs/{job_id} | Statut, décision de niveau, utilisation, facturation et lien groupé pour une tâche. |
| OBTENIR | /v1/jobs | Listez vos emplois, les plus récents en premier. Prend en charge ?status= et la pagination du curseur. |
| OBTENIR | /v1/jobs/{job_id}/moderation | Verdict de modération d'une tâche. Renvoie 404 lorsque la modération n'a pas été demandée. |
| GET | /v1/jobs/{job_id}/clip-candidates | Vérifier avant le rendu |
| OBTENIR | /v1/jobs/{job_id}/media-report | Rapport médico-légal pour un travail. 404 lorsque media_report_v1 n’a pas été demandé. |
| OBTENIR | /v1/jobs/{job_id}/compatibility-report | Verdict de compatibilité versionné. 404 lorsque compatibility_report_v1 n’a pas été demandé. |
| OBTENIR | /v1/jobs/{job_id}/codes | Détections QR et codes-barres limitées avec références de preuve. 404 lorsque code_detect_v1 n’a pas été demandé. |
| OBTENIR | /v1/jobs/{job_id}/bundle?token=... | Échangez le jeton limité à la tâche contre un ensemble ; aucune clé API n’est requise. |
| POSTER | /v1/jobs/{job_id}/retry-webhook | Réessayez le webhook du terminal pour une tâche que vous possédez. |
| POSTER | /v1/account/watermark-logo/upload-url | Créez une cible de téléchargement pour le logo du compte PNG. |
| POSTER | /v1/account/watermark-logo/confirm | Confirmez le logo et ses paramètres de placement. |
Utilisez le document OpenAPI 3.1 versionné pour générer des clients, valider les requêtes et examiner le contrat. Il contient uniquement l’API publique prise en charge et ne nécessite aucune clé API.